Esempio n. 1
0
            public TestCaseContext()
            {
                Options    = AssetsOptions.Default;
                Descriptor = new AssetDescriptor
                {
                    Key       = "d",
                    AssetPath = "root/d",
                    AssetType = AssetType.Text
                };
                Locale                 = Defaults.Locale;
                AssetBytes             = new byte[] { 0x01, 0x02, 0x03 };
                AssetDataStringEncoded = "AssetDataStringEncoded";
                AssetDataBase64Encoded = "AssetDataBase64Encoded";

                OptionsService         = Mock.Of <IOptions <AssetsOptions> >();
                Logger                 = Mock.Of <ILogger <AssetsManager> >();
                AssetDescriptorsCache  = Mock.Of <IAssetDescriptorsCache>();
                StringEncoder          = Mock.Of <IStringEncoder>();
                Base64Encoder          = Mock.Of <IBase64Encoder>();
                TextAssetDataProcessor = Mock.Of <ITextAssetDataProcessor>();
                DataService            = Mock.Of <IAssetManagerDataService>();

                Mock.Get(OptionsService).Setup(
                    m => m.Value)
                .Returns(Options);

                Mock.Get(AssetDescriptorsCache).Setup(
                    m => m.GetAssetDescriptor(It.IsAny <string>()))
                .Returns(Descriptor);

                Mock.Get(DataService).Setup(
                    m => m.ReadAssetBytesAsync(
                        Options.AssetsDir,
                        It.IsAny <Asset>(),
                        It.IsAny <CancellationToken>()))
                .ReturnsAsync(AssetBytes);

                Mock.Get(TextAssetDataProcessor).Setup(
                    m => m.ProcessData(AssetBytes))
                .Returns(AssetBytes);

                Mock.Get(StringEncoder).Setup(
                    m => m.EncodeToString(AssetBytes))
                .Returns(AssetDataStringEncoded);

                Mock.Get(Base64Encoder).Setup(
                    m => m.Encode(AssetBytes))
                .Returns(AssetDataBase64Encoded);
            }
        public IActionResult SendToAddress(Asset asset)
        {
            CheckWallet();
            UInt160         assetId    = UInt160.Parse(asset.AssetId);
            UInt160         scriptHash = asset.Address.ToScriptHash();
            AssetDescriptor descriptor = new AssetDescriptor(assetId);
            BigDecimal      amount     = BigDecimal.Parse(asset.Value, descriptor.Decimals);

            if (amount.Sign <= 0)
            {
                throw new RestException(-32602, "Invalid params");
            }
            Transaction tx = wallet.MakeTransaction(new[]
            {
                new TransferOutput
                {
                    AssetId    = assetId,
                    Value      = amount,
                    ScriptHash = scriptHash
                }
            });

            if (tx == null)
            {
                throw new RestException(-300, "Insufficient funds");
            }

            ContractParametersContext transContext = new ContractParametersContext(tx);

            wallet.Sign(transContext);
            if (!transContext.Completed)
            {
                return(FormatJson(transContext.ToJson()));
            }
            tx.Witnesses = transContext.GetWitnesses();
            if (tx.Size > 1024)
            {
                long calFee = tx.Size * 1000 + 100000;
                if (tx.NetworkFee < calFee)
                {
                    tx.NetworkFee = calFee;
                }
            }
            if (tx.NetworkFee > RestSettings.Default.MaxFee)
            {
                throw new RestException(-301, "The necessary fee is more than the Max_fee, this transaction is failed. Please increase your Max_fee value.");
            }
            return(FormatJson(SignAndRelay(tx)));
        }
Esempio n. 3
0
        protected virtual JObject SendToAddress(JArray _params)
        {
            CheckWallet();
            UInt160         assetId    = UInt160.Parse(_params[0].AsString());
            UInt160         to         = AddressToScriptHash(_params[1].AsString());
            AssetDescriptor descriptor = new AssetDescriptor(assetId);
            BigDecimal      amount     = BigDecimal.Parse(_params[2].AsString(), descriptor.Decimals);

            if (amount.Sign <= 0)
            {
                throw new RpcException(-32602, "Invalid params");
            }
            Transaction tx = wallet.MakeTransaction(new[]
            {
                new TransferOutput
                {
                    AssetId    = assetId,
                    Value      = amount,
                    ScriptHash = to
                }
            });

            if (tx == null)
            {
                throw new RpcException(-300, "Insufficient funds");
            }

            ContractParametersContext transContext = new ContractParametersContext(tx);

            wallet.Sign(transContext);
            if (!transContext.Completed)
            {
                return(transContext.ToJson());
            }
            tx.Witnesses = transContext.GetWitnesses();
            if (tx.Size > 1024)
            {
                long calFee = tx.Size * 1000 + 100000;
                if (tx.NetworkFee < calFee)
                {
                    tx.NetworkFee = calFee;
                }
            }
            if (tx.NetworkFee > settings.MaxFee)
            {
                throw new RpcException(-301, "The necessary fee is more than the Max_fee, this transaction is failed. Please increase your Max_fee value.");
            }
            return(SignAndRelay(tx));
        }
Esempio n. 4
0
        public void DownloadAsset(AssetDescriptor asset)
        {
            if (asset == null)
            {
                throw new ArgumentNullException("asset");
            }

            if (isAssetDownloading)
            {
                downloadQueue.Enqueue(asset);
                return;
            }

            _DownloadAsset(asset);
        }
Esempio n. 5
0
        public static bool IsRemotePresent(AssetDescriptor desc)
        {
            Process process = Process("config --file .gitmodules --list", "..");

            process.WaitForExit();
            string output = process?.StandardError.ReadToEnd();

            if (!string.IsNullOrEmpty(output))
            {
                throw new Exception("Git error: " + output);
            }

            output = process?.StandardOutput.ReadToEnd();
            return(output.Contains(desc.gitURI));
        }
Esempio n. 6
0
        private void _DownloadAsset(AssetDescriptor asset)
        {
            webClient = new WebClient();

            // Hook in the async delegates
            webClient.DownloadProgressChanged += ProgressChanged;
            webClient.DownloadDataCompleted   += Completed;

            // Off we go!
            currentDescriptor = asset;

            webClient.DownloadDataAsync(new Uri(baseDirectoryUrl + asset.Name + asset.Compression));
            isAssetDownloading = true;
            OnAssetDownloadBegin(asset);
        }
Esempio n. 7
0
        private void OnBalanceOfCommand(UInt160 tokenHash, UInt160 address)
        {
            var arg = new JObject();

            arg["type"]  = "Hash160";
            arg["value"] = address.ToString();

            var asset = new AssetDescriptor(tokenHash);

            var balanceResult = OnInvokeWithResult(tokenHash, "balanceOf", null, new JArray(arg));
            var balance       = new BigDecimal(((PrimitiveType)balanceResult).GetInteger(), asset.Decimals);

            Console.WriteLine();
            Console.WriteLine($"{asset.AssetName} balance: {balance}");
        }
Esempio n. 8
0
        public TxOutListBoxItem[] GetOutputs()
        {
            AssetDescriptor asset = (AssetDescriptor)comboBox1.SelectedItem;

            return(textBox1.Lines.Where(p => !string.IsNullOrWhiteSpace(p)).Select(p =>
            {
                string[] line = p.Split(new[] { ' ', '\t', ',' }, StringSplitOptions.RemoveEmptyEntries);
                return new TxOutListBoxItem
                {
                    AssetName = asset.AssetName,
                    AssetId = asset.AssetId,
                    Value = new BigDecimal(Fixed8.Parse(line[1]).GetData(), 8),
                    ScriptHash = Wallet.ToScriptHash(line[0])
                };
            }).Where(p => p.Value.Value != 0).ToArray());
        }
Esempio n. 9
0
        public TxOutListBoxItem[] GetOutputs()
        {
            AssetDescriptor asset = (AssetDescriptor)comboBox1.SelectedItem;

            return(textBox1.Lines.Where(p => !string.IsNullOrWhiteSpace(p)).Select(p =>
            {
                string[] line = p.Split(new[] { ' ', '\t', ',' }, StringSplitOptions.RemoveEmptyEntries);
                return new TxOutListBoxItem
                {
                    AssetName = asset.AssetName == "NEO" ? "CRONIUM" : asset.AssetName == "NeoGas" ? "CRON" : asset.AssetName,
                    AssetId = asset.AssetId,
                    Value = BigDecimal.Parse(line[1], asset.Decimals),
                    ScriptHash = line[0].ToScriptHash()
                };
            }).Where(p => p.Value.Value != 0).ToArray());
        }
Esempio n. 10
0
        private JObject SendFrom(UInt160 assetId, UInt160 from, UInt160 to, string value)
        {
            CheckWallet();
            AssetDescriptor descriptor = new AssetDescriptor(assetId);
            BigDecimal      amount     = BigDecimal.Parse(value, descriptor.Decimals);

            if (amount.Sign <= 0)
            {
                throw new RpcException(-32602, "Invalid params");
            }
            Transaction tx = Wallet.MakeTransaction(new[]
            {
                new TransferOutput
                {
                    AssetId    = assetId,
                    Value      = amount,
                    ScriptHash = to
                }
            }, from);

            if (tx == null)
            {
                throw new RpcException(-300, "Insufficient funds");
            }

            ContractParametersContext transContext = new ContractParametersContext(tx);

            Wallet.Sign(transContext);
            if (!transContext.Completed)
            {
                return(transContext.ToJson());
            }
            tx.Witnesses = transContext.GetWitnesses();
            if (tx.Size > 1024)
            {
                long calFee = tx.Size * 1000 + 100000;
                if (tx.NetworkFee < calFee)
                {
                    tx.NetworkFee = calFee;
                }
            }
            if (tx.NetworkFee > Settings.Default.MaxFee)
            {
                throw new RpcException(-301, "The necessary fee is more than the Max_fee, this transaction is failed. Please increase your Max_fee value.");
            }
            return(SignAndRelay(tx));
        }
Esempio n. 11
0
        private JObject SendToAddress(UIntBase assetId, UInt160 scriptHash, string value, Fixed8 fee, UInt160 change_address)
        {
            CheckWallet();
            AssetDescriptor descriptor = new AssetDescriptor(assetId);
            BigDecimal      amount     = BigDecimal.Parse(value, descriptor.Decimals);

            if (amount.Sign <= 0)
            {
                throw new RpcException(-32602, "Invalid params");
            }
            if (fee < Fixed8.Zero)
            {
                throw new RpcException(-32602, "Invalid params");
            }
            Transaction tx = Wallet.MakeTransaction(null, new[]
            {
                new TransferOutput
                {
                    AssetId    = assetId,
                    Value      = amount,
                    ScriptHash = scriptHash
                }
            }, change_address: change_address, fee: fee);

            if (tx.Size > 1024)
            {
                fee = Fixed8.Max(Fixed8.FromDecimal(tx.Size * 0.00001m + 0.001m), fee);
                tx  = Wallet.MakeTransaction(null, new[]
                {
                    new TransferOutput
                    {
                        AssetId    = assetId,
                        Value      = amount,
                        ScriptHash = scriptHash
                    }
                }, change_address: change_address, fee: fee);
            }
            if (tx == null)
            {
                throw new RpcException(-300, "Insufficient funds");
            }
            if (fee > Settings.Default.MaxFee)
            {
                throw new RpcException(-301, "The necessary fee is more than the Max_fee, this transaction is failed. Please increase your Max_fee value.");
            }
            return(SignAndRelay(tx));
        }
Esempio n. 12
0
        public static AssetDescriptor CustomAssetDescriptor(UInt256 asset_id)
        {
            AssetDescriptor desc = new AssetDescriptor(asset_id);

            if (desc != null)
            {
                if (desc.AssetName == "NEO")
                {
                    desc.AssetName = "CRONIUM";
                }
                if (desc.AssetName == "NeoGas")
                {
                    desc.AssetName = "CRON";
                }
            }
            return(desc);
        }
        /// <summary>
        /// Starts downloading each asset given and updating our controller
        /// </summary>
        private void DownloadAsset(AssetDescriptor asset)
        {
            if (asset == null)
            {
                ++numFilesToDownload;
                return;
            }

            //Are we already downloading?
            if (isDownloading)
            { //We are, queue it up
                downloadQueue.Enqueue(asset);
            }
            else
            {
                StartDequeuing(asset);
            }
        }
        private void StartDequeuing(AssetDescriptor asset)
        {
            currentAssetDescriptor = asset;

            WebClient webClient = new WebClient();

            webClient.DownloadDataCompleted += new DownloadDataCompletedEventHandler(AssetDownloadingComplete);
            try
            {
                webClient.DownloadDataAsync(new Uri(CurrentUrl + asset.Name));
            }
            catch (Exception e)
            {
                Log.Write(e.ToString());
            }

            isDownloading = true;
        }
Esempio n. 15
0
        private JObject SendMany(UInt160 from, JArray to, Fixed8 fee, UInt160 change_address)
        {
            CheckWallet();
            if (to.Count == 0)
            {
                throw new RpcException(-32602, "Invalid params");
            }
            TransferOutput[] outputs = new TransferOutput[to.Count];
            for (int i = 0; i < to.Count; i++)
            {
                UIntBase        asset_id   = UIntBase.Parse(to[i]["asset"].AsString());
                AssetDescriptor descriptor = new AssetDescriptor(asset_id);
                outputs[i] = new TransferOutput
                {
                    AssetId    = asset_id,
                    Value      = BigDecimal.Parse(to[i]["value"].AsString(), descriptor.Decimals),
                    ScriptHash = to[i]["address"].AsString().ToScriptHash()
                };
                if (outputs[i].Value.Sign <= 0)
                {
                    throw new RpcException(-32602, "Invalid params");
                }
            }
            if (fee < Fixed8.Zero)
            {
                throw new RpcException(-32602, "Invalid params");
            }
            Transaction tx = Wallet.MakeTransaction(null, outputs, from: from, change_address: change_address, fee: fee);

            if (tx.Size > 1024)
            {
                fee = Fixed8.Max(Fixed8.FromDecimal(tx.Size * 0.00001m + 0.001m), fee);
                tx  = Wallet.MakeTransaction(null, outputs, from: from, change_address: change_address, fee: fee);
            }
            if (tx == null)
            {
                throw new RpcException(-300, "Insufficient funds");
            }
            if (fee > Settings.Default.MaxFee)
            {
                throw new RpcException(-301, "The necessary fee is more than the Max_fee, this transaction is failed. Please increase your Max_fee value.");
            }
            return(SignAndRelay(tx));
        }
Esempio n. 16
0
        private JObject SendToAddress(UIntBase assetId, UInt160 scriptHash, string value, Fixed8 fee, UInt160 change_address)
        {
            CheckWallet();
            AssetDescriptor descriptor = new AssetDescriptor(assetId);
            BigDecimal      amount     = BigDecimal.Parse(value, descriptor.Decimals);

            if (amount.Sign <= 0)
            {
                throw new RpcException(-32602, "Invalid params");
            }
            if (fee < Fixed8.Zero)
            {
                throw new RpcException(-32602, "Invalid params");
            }
            Transaction tx = Wallet.MakeTransaction(null, new[]
            {
                new TransferOutput
                {
                    AssetId    = assetId,
                    Value      = amount,
                    ScriptHash = scriptHash
                }
            }, change_address: change_address, fee: fee);

            if (tx.Size > 1024)
            {
                fee += Fixed8.FromDecimal(tx.Size * 0.00001m + 0.001m);
                tx   = Wallet.MakeTransaction(null, new[]
                {
                    new TransferOutput
                    {
                        AssetId    = assetId,
                        Value      = amount,
                        ScriptHash = scriptHash
                    }
                }, change_address: change_address, fee: fee);
            }
            if (tx == null)
            {
                throw new RpcException(-300, "Insufficient funds");
            }
            return(SignAndRelay(tx));
        }
Esempio n. 17
0
        private void OnTransferCommand(UInt160 tokenHash, UInt160 to, decimal amount, UInt160 from = null, string data = null, UInt160[] signersAccounts = null)
        {
            var snapshot = NeoSystem.StoreView;
            var asset    = new AssetDescriptor(snapshot, NeoSystem.Settings, tokenHash);
            var value    = new BigDecimal(amount, asset.Decimals);

            if (NoWallet())
            {
                return;
            }

            Transaction tx;

            try
            {
                tx = CurrentWallet.MakeTransaction(snapshot, new[]
                {
                    new TransferOutput
                    {
                        AssetId    = tokenHash,
                        Value      = value,
                        ScriptHash = to,
                        Data       = data
                    }
                }, from: from, cosigners: signersAccounts?.Select(p => new Signer
                {
                    // default access for transfers should be valid only for first invocation
                    Scopes  = WitnessScope.CalledByEntry,
                    Account = p
                })
                                                   .ToArray() ?? Array.Empty <Signer>());
            }
            catch (InvalidOperationException e)
            {
                ConsoleHelper.Error(GetExceptionMessage(e));
                return;
            }
            if (!ReadUserInput("Relay tx(no|yes)").IsYes())
            {
                return;
            }
            SignAndSendTx(snapshot, tx);
        }
Esempio n. 18
0
        private void OnBalanceOfCommand(UInt160 tokenHash, UInt160 address)
        {
            var arg = new JObject();

            arg["type"]  = "Hash160";
            arg["value"] = address.ToString();

            var asset = new AssetDescriptor(NeoSystem.StoreView, NeoSystem.Settings, tokenHash);

            if (!OnInvokeWithResult(tokenHash, "balanceOf", out StackItem balanceResult, null, new JArray(arg)))
            {
                return;
            }

            var balance = new BigDecimal(((PrimitiveType)balanceResult).GetInteger(), asset.Decimals);

            Console.WriteLine();
            ConsoleHelper.Info($"{asset.AssetName} balance: ", $"{balance}");
        }
        /// <summary>
        /// Starts downloading each asset given and updating our controller
        /// </summary>
        private void DownloadAsset(AssetDescriptor asset)
        {
            if (asset == null)
            {
                Log.Write(string.Format("Asset doesn't exist. Current: {0} Total: {1}", numFilesToDownload, totalFilesToDownload));
                ++numFilesToDownload;
                return;
            }

            //Are we already downloading?
            if (isDownloading)
            { //We are, queue it up
                downloadQueue.Enqueue(asset);
            }
            else
            {
                StartDequeuing(asset);
            }
        }
Esempio n. 20
0
        private void OnTransferCommand(UInt160 tokenHash, UInt160 to, decimal amount, string data = null, UInt160 from = null, UInt160[] signersAccounts = null)
        {
            var asset = new AssetDescriptor(tokenHash);
            var value = BigDecimal.Parse(amount.ToString(CultureInfo.InvariantCulture), asset.Decimals);

            if (NoWallet())
            {
                return;
            }

            Transaction tx;

            try
            {
                tx = CurrentWallet.MakeTransaction(new[]
                {
                    new TransferOutput
                    {
                        AssetId    = tokenHash,
                        Value      = value,
                        ScriptHash = to,
                        Data       = data
                    }
                }, from: from, cosigners: signersAccounts?.Select(p => new Signer
                {
                    // default access for transfers should be valid only for first invocation
                    Scopes  = WitnessScope.CalledByEntry,
                    Account = p
                })
                                                   .ToArray() ?? new Signer[0]);
            }
            catch (InvalidOperationException e)
            {
                Console.WriteLine("Error: " + GetExceptionMessage(e));
                return;
            }
            if (!ReadUserInput("Relay tx(no|yes)").IsYes())
            {
                return;
            }
            SignAndSendTx(tx);
        }
Esempio n. 21
0
        private bool InitWallet()
        {
            if (Wallet == null)
            {
                Console.WriteLine("no wallet found");
                return(false);
            }

            if (NEO != null)
            {
                return(true);
            }

            // Open wallet

            NEO = new AssetDescriptor(NativeContract.NEO.Hash);
            GAS = new AssetDescriptor(NativeContract.GAS.Hash);

            return(true);
        }
        /// <summary>
        /// Starts downloading each asset given and updating our controller
        /// </summary>
        private void DownloadAsset(AssetDescriptor asset)
        {
            if (asset == null)
            {
                if (errorInDownloads == null)
                {
                    errorInDownloads = new List <string>();
                }
                LogWrite(string.Format("Asset doesn't exist.(Null) Current: {0} Total: {1}", numFilesToDownload.ToString(), totalFilesToDownload.ToString()));
                ++numFilesToDownload;
                return;
            }

            //Are we already downloading?
            if (isDownloading)
            { //We are, queue it up
                downloadQueue.Enqueue(asset);
            }
            else
            {
                StartDequeuing(asset);
            }
        }
Esempio n. 23
0
        public async Task GetAsset_DataEncoding_Default_Mapped(
            AssetType assetType,
            AssetDataEncoding expected)
        {
            // Arrange
            var context = new TestCaseContext();
            var sut     = new AssetsManager(
                context.OptionsService,
                context.Logger,
                context.AssetDescriptorsCache,
                context.StringEncoder,
                context.Base64Encoder,
                context.TextAssetDataProcessor,
                context.DataService);

            var key        = "d";
            var descriptor = new AssetDescriptor
            {
                Key       = key,
                AssetType = assetType,
                AssetPath = key
            };

            // Act
            var asset = assetType switch
            {
                AssetType.Text => await sut.GetTextAsset(descriptor, context.Locale),
                AssetType.Image => await sut.GetImageAsset(descriptor, context.Locale),
                AssetType.State => await sut.GetStateAsset(descriptor, context.Locale),
                AssetType.Script => await sut.GetScriptAsset(descriptor, context.Locale),
                _ => throw new NotImplementedException()
            };

            // Assert
            Assert.NotNull(asset);
            Assert.Equal(expected, asset.DataEncoding);
        }
Esempio n. 24
0
 public BulkPayDialog(AssetDescriptor asset = null)
 {
     InitializeComponent();
     if (asset == null)
     {
         foreach (UInt160 assetId in NEP5Watched)
         {
             try
             {
                 comboBox1.Items.Add(new AssetDescriptor(Service.NeoSystem.StoreView, Service.NeoSystem.Settings, assetId));
             }
             catch (ArgumentException)
             {
                 continue;
             }
         }
     }
     else
     {
         comboBox1.Items.Add(asset);
         comboBox1.SelectedIndex = 0;
         comboBox1.Enabled       = false;
     }
 }
Esempio n. 25
0
        private JObject Process(string method, JArray _params)
        {
            switch (method)
            {
            case "dumpprivkey":
                if (wallet == null)
                {
                    throw new RpcException(-400, "Access denied");
                }
                else
                {
                    UInt160       scriptHash = _params[0].AsString().ToScriptHash();
                    WalletAccount account    = wallet.GetAccount(scriptHash);
                    return(account.GetKey().Export());
                }

            case "getaccountstate":
            {
                UInt160      script_hash = _params[0].AsString().ToScriptHash();
                AccountState account     = Blockchain.Singleton.Store.GetAccounts().TryGet(script_hash) ?? new AccountState(script_hash);
                return(account.ToJson());
            }

            case "getassetstate":
            {
                UInt256    asset_id = UInt256.Parse(_params[0].AsString());
                AssetState asset    = Blockchain.Singleton.Store.GetAssets().TryGet(asset_id);
                return(asset?.ToJson() ?? throw new RpcException(-100, "Unknown asset"));
            }

            case "getbalance":
                if (wallet == null)
                {
                    throw new RpcException(-400, "Access denied.");
                }
                else
                {
                    JObject json = new JObject();
                    switch (UIntBase.Parse(_params[0].AsString()))
                    {
                    case UInt160 asset_id_160:         //NEP-5 balance
                        json["balance"] = wallet.GetAvailable(asset_id_160).ToString();
                        break;

                    case UInt256 asset_id_256:         //Global Assets balance
                        IEnumerable <Coin> coins = wallet.GetCoins().Where(p => !p.State.HasFlag(CoinState.Spent) && p.Output.AssetId.Equals(asset_id_256));
                        json["balance"]   = coins.Sum(p => p.Output.Value).ToString();
                        json["confirmed"] = coins.Where(p => p.State.HasFlag(CoinState.Confirmed)).Sum(p => p.Output.Value).ToString();
                        break;
                    }
                    return(json);
                }

            case "getbestblockhash":
                return(Blockchain.Singleton.CurrentBlockHash.ToString());

            case "getblock":
            {
                Block block;
                if (_params[0] is JNumber)
                {
                    uint index = (uint)_params[0].AsNumber();
                    block = Blockchain.Singleton.Store.GetBlock(index);
                }
                else
                {
                    UInt256 hash = UInt256.Parse(_params[0].AsString());
                    block = Blockchain.Singleton.Store.GetBlock(hash);
                }
                if (block == null)
                {
                    throw new RpcException(-100, "Unknown block");
                }
                bool verbose = _params.Count >= 2 && _params[1].AsBooleanOrDefault(false);
                if (verbose)
                {
                    JObject json = block.ToJson();
                    json["confirmations"] = Blockchain.Singleton.Height - block.Index + 1;
                    UInt256 hash = Blockchain.Singleton.Store.GetNextBlockHash(block.Hash);
                    if (hash != null)
                    {
                        json["nextblockhash"] = hash.ToString();
                    }
                    return(json);
                }
                return(block.ToArray().ToHexString());
            }

            case "getblockcount":
                return(Blockchain.Singleton.Height + 1);

            case "getblockhash":
            {
                uint height = (uint)_params[0].AsNumber();
                if (height <= Blockchain.Singleton.Height)
                {
                    return(Blockchain.Singleton.GetBlockHash(height).ToString());
                }
                throw new RpcException(-100, "Invalid Height");
            }

            case "getblockheader":
            {
                Header header;
                if (_params[0] is JNumber)
                {
                    uint height = (uint)_params[0].AsNumber();
                    header = Blockchain.Singleton.Store.GetHeader(height);
                }
                else
                {
                    UInt256 hash = UInt256.Parse(_params[0].AsString());
                    header = Blockchain.Singleton.Store.GetHeader(hash);
                }
                if (header == null)
                {
                    throw new RpcException(-100, "Unknown block");
                }

                bool verbose = _params.Count >= 2 && _params[1].AsBooleanOrDefault(false);
                if (verbose)
                {
                    JObject json = header.ToJson();
                    json["confirmations"] = Blockchain.Singleton.Height - header.Index + 1;
                    UInt256 hash = Blockchain.Singleton.Store.GetNextBlockHash(header.Hash);
                    if (hash != null)
                    {
                        json["nextblockhash"] = hash.ToString();
                    }
                    return(json);
                }

                return(header.ToArray().ToHexString());
            }

            case "getblocksysfee":
            {
                uint height = (uint)_params[0].AsNumber();
                if (height <= Blockchain.Singleton.Height)
                {
                    return(Blockchain.Singleton.Store.GetSysFeeAmount(height).ToString());
                }
                throw new RpcException(-100, "Invalid Height");
            }

            case "getconnectioncount":
                return(LocalNode.Singleton.ConnectedCount);

            case "getcontractstate":
            {
                UInt160       script_hash = UInt160.Parse(_params[0].AsString());
                ContractState contract    = Blockchain.Singleton.Store.GetContracts().TryGet(script_hash);
                return(contract?.ToJson() ?? throw new RpcException(-100, "Unknown contract"));
            }

            case "getnewaddress":
                if (wallet == null)
                {
                    throw new RpcException(-400, "Access denied");
                }
                else
                {
                    WalletAccount account = wallet.CreateAccount();
                    if (wallet is NEP6Wallet nep6)
                    {
                        nep6.Save();
                    }
                    return(account.Address);
                }

            case "getpeers":
            {
                JObject json = new JObject();
                json["unconnected"] = new JArray(LocalNode.Singleton.GetUnconnectedPeers().Select(p =>
                    {
                        JObject peerJson    = new JObject();
                        peerJson["address"] = p.Address.ToString();
                        peerJson["port"]    = p.Port;
                        return(peerJson);
                    }));
                json["bad"]       = new JArray();   //badpeers has been removed
                json["connected"] = new JArray(LocalNode.Singleton.GetRemoteNodes().Select(p =>
                    {
                        JObject peerJson    = new JObject();
                        peerJson["address"] = p.Remote.Address.ToString();
                        peerJson["port"]    = p.ListenerPort;
                        return(peerJson);
                    }));
                return(json);
            }

            case "getrawmempool":
                return(new JArray(Blockchain.Singleton.GetMemoryPool().Select(p => (JObject)p.Hash.ToString())));

            case "getrawtransaction":
            {
                UInt256     hash    = UInt256.Parse(_params[0].AsString());
                bool        verbose = _params.Count >= 2 && _params[1].AsBooleanOrDefault(false);
                Transaction tx      = Blockchain.Singleton.GetTransaction(hash);
                if (tx == null)
                {
                    throw new RpcException(-100, "Unknown transaction");
                }
                if (verbose)
                {
                    JObject json   = tx.ToJson();
                    uint?   height = Blockchain.Singleton.Store.GetTransactions().TryGet(hash)?.BlockIndex;
                    if (height != null)
                    {
                        Header header = Blockchain.Singleton.Store.GetHeader((uint)height);
                        json["blockhash"]     = header.Hash.ToString();
                        json["confirmations"] = Blockchain.Singleton.Height - header.Index + 1;
                        json["blocktime"]     = header.Timestamp;
                    }
                    return(json);
                }
                return(tx.ToArray().ToHexString());
            }

            case "getstorage":
            {
                UInt160     script_hash = UInt160.Parse(_params[0].AsString());
                byte[]      key         = _params[1].AsString().HexToBytes();
                StorageItem item        = Blockchain.Singleton.Store.GetStorages().TryGet(new StorageKey
                    {
                        ScriptHash = script_hash,
                        Key        = key
                    }) ?? new StorageItem();
                return(item.Value?.ToHexString());
            }

            case "gettxout":
            {
                UInt256 hash  = UInt256.Parse(_params[0].AsString());
                ushort  index = (ushort)_params[1].AsNumber();
                return(Blockchain.Singleton.Store.GetUnspent(hash, index)?.ToJson(index));
            }

            case "getvalidators":
                using (Snapshot snapshot = Blockchain.Singleton.GetSnapshot())
                {
                    var validators = snapshot.GetValidators();
                    return(snapshot.GetEnrollments().Select(p =>
                    {
                        JObject validator = new JObject();
                        validator["publickey"] = p.PublicKey.ToString();
                        validator["votes"] = p.Votes.ToString();
                        validator["active"] = validators.Contains(p.PublicKey);
                        return validator;
                    }).ToArray());
                }

            case "getversion":
            {
                JObject json = new JObject();
                json["port"]      = LocalNode.Singleton.ListenerPort;
                json["nonce"]     = LocalNode.Nonce;
                json["useragent"] = LocalNode.UserAgent;
                return(json);
            }

            case "getwalletheight":
                if (wallet == null)
                {
                    throw new RpcException(-400, "Access denied.");
                }
                else
                {
                    return((wallet.WalletHeight > 0) ? wallet.WalletHeight - 1 : 0);
                }

            case "invoke":
            {
                UInt160             script_hash = UInt160.Parse(_params[0].AsString());
                ContractParameter[] parameters  = ((JArray)_params[1]).Select(p => ContractParameter.FromJson(p)).ToArray();
                byte[] script;
                using (ScriptBuilder sb = new ScriptBuilder())
                {
                    script = sb.EmitAppCall(script_hash, parameters).ToArray();
                }
                return(GetInvokeResult(script));
            }

            case "invokefunction":
            {
                UInt160             script_hash = UInt160.Parse(_params[0].AsString());
                string              operation   = _params[1].AsString();
                ContractParameter[] args        = _params.Count >= 3 ? ((JArray)_params[2]).Select(p => ContractParameter.FromJson(p)).ToArray() : new ContractParameter[0];
                byte[]              script;
                using (ScriptBuilder sb = new ScriptBuilder())
                {
                    script = sb.EmitAppCall(script_hash, operation, args).ToArray();
                }
                return(GetInvokeResult(script));
            }

            case "invokescript":
            {
                byte[] script = _params[0].AsString().HexToBytes();
                return(GetInvokeResult(script));
            }

            case "listaddress":
                if (wallet == null)
                {
                    throw new RpcException(-400, "Access denied.");
                }
                else
                {
                    return(wallet.GetAccounts().Select(p =>
                    {
                        JObject account = new JObject();
                        account["address"] = p.Address;
                        account["haskey"] = p.HasKey;
                        account["label"] = p.Label;
                        account["watchonly"] = p.WatchOnly;
                        return account;
                    }).ToArray());
                }

            case "sendfrom":
                if (wallet == null)
                {
                    throw new RpcException(-400, "Access denied");
                }
                else
                {
                    UIntBase        assetId    = UIntBase.Parse(_params[0].AsString());
                    AssetDescriptor descriptor = new AssetDescriptor(assetId);
                    UInt160         from       = _params[1].AsString().ToScriptHash();
                    UInt160         to         = _params[2].AsString().ToScriptHash();
                    BigDecimal      value      = BigDecimal.Parse(_params[3].AsString(), descriptor.Decimals);
                    if (value.Sign <= 0)
                    {
                        throw new RpcException(-32602, "Invalid params");
                    }
                    Fixed8 fee = _params.Count >= 5 ? Fixed8.Parse(_params[4].AsString()) : Fixed8.Zero;
                    if (fee < Fixed8.Zero)
                    {
                        throw new RpcException(-32602, "Invalid params");
                    }
                    UInt160     change_address = _params.Count >= 6 ? _params[5].AsString().ToScriptHash() : null;
                    Transaction tx             = wallet.MakeTransaction(null, new[]
                    {
                        new TransferOutput
                        {
                            AssetId    = assetId,
                            Value      = value,
                            ScriptHash = to
                        }
                    }, from: from, change_address: change_address, fee: fee);
                    if (tx == null)
                    {
                        throw new RpcException(-300, "Insufficient funds");
                    }
                    ContractParametersContext context = new ContractParametersContext(tx);
                    wallet.Sign(context);
                    if (context.Completed)
                    {
                        tx.Witnesses = context.GetWitnesses();
                        wallet.ApplyTransaction(tx);
                        system.LocalNode.Tell(new LocalNode.Relay {
                            Inventory = tx
                        });
                        return(tx.ToJson());
                    }
                    else
                    {
                        return(context.ToJson());
                    }
                }

            case "sendmany":
                if (wallet == null)
                {
                    throw new RpcException(-400, "Access denied");
                }
                else
                {
                    JArray to = (JArray)_params[0];
                    if (to.Count == 0)
                    {
                        throw new RpcException(-32602, "Invalid params");
                    }
                    TransferOutput[] outputs = new TransferOutput[to.Count];
                    for (int i = 0; i < to.Count; i++)
                    {
                        UIntBase        asset_id   = UIntBase.Parse(to[i]["asset"].AsString());
                        AssetDescriptor descriptor = new AssetDescriptor(asset_id);
                        outputs[i] = new TransferOutput
                        {
                            AssetId    = asset_id,
                            Value      = BigDecimal.Parse(to[i]["value"].AsString(), descriptor.Decimals),
                            ScriptHash = to[i]["address"].AsString().ToScriptHash()
                        };
                        if (outputs[i].Value.Sign <= 0)
                        {
                            throw new RpcException(-32602, "Invalid params");
                        }
                    }
                    Fixed8 fee = _params.Count >= 2 ? Fixed8.Parse(_params[1].AsString()) : Fixed8.Zero;
                    if (fee < Fixed8.Zero)
                    {
                        throw new RpcException(-32602, "Invalid params");
                    }
                    UInt160     change_address = _params.Count >= 3 ? _params[2].AsString().ToScriptHash() : null;
                    Transaction tx             = wallet.MakeTransaction(null, outputs, change_address: change_address, fee: fee);
                    if (tx == null)
                    {
                        throw new RpcException(-300, "Insufficient funds");
                    }
                    ContractParametersContext context = new ContractParametersContext(tx);
                    wallet.Sign(context);
                    if (context.Completed)
                    {
                        tx.Witnesses = context.GetWitnesses();
                        wallet.ApplyTransaction(tx);
                        system.LocalNode.Tell(new LocalNode.Relay {
                            Inventory = tx
                        });
                        return(tx.ToJson());
                    }
                    else
                    {
                        return(context.ToJson());
                    }
                }

            case "sendrawtransaction":
            {
                Transaction tx = Transaction.DeserializeFrom(_params[0].AsString().HexToBytes());
                Neo.SmartContract.Debug.DumpInfo.RegNeedLog(tx.Hash);
                RelayResultReason reason = system.Blockchain.Ask <RelayResultReason>(tx).Result;
                return(GetRelayResult(reason));
            }

            case "sendtoaddress":
                if (wallet == null)
                {
                    throw new RpcException(-400, "Access denied");
                }
                else
                {
                    UIntBase        assetId    = UIntBase.Parse(_params[0].AsString());
                    AssetDescriptor descriptor = new AssetDescriptor(assetId);
                    UInt160         scriptHash = _params[1].AsString().ToScriptHash();
                    BigDecimal      value      = BigDecimal.Parse(_params[2].AsString(), descriptor.Decimals);
                    if (value.Sign <= 0)
                    {
                        throw new RpcException(-32602, "Invalid params");
                    }
                    Fixed8 fee = _params.Count >= 4 ? Fixed8.Parse(_params[3].AsString()) : Fixed8.Zero;
                    if (fee < Fixed8.Zero)
                    {
                        throw new RpcException(-32602, "Invalid params");
                    }
                    UInt160     change_address = _params.Count >= 5 ? _params[4].AsString().ToScriptHash() : null;
                    Transaction tx             = wallet.MakeTransaction(null, new[]
                    {
                        new TransferOutput
                        {
                            AssetId    = assetId,
                            Value      = value,
                            ScriptHash = scriptHash
                        }
                    }, change_address: change_address, fee: fee);
                    if (tx == null)
                    {
                        throw new RpcException(-300, "Insufficient funds");
                    }
                    ContractParametersContext context = new ContractParametersContext(tx);
                    wallet.Sign(context);
                    if (context.Completed)
                    {
                        tx.Witnesses = context.GetWitnesses();
                        wallet.ApplyTransaction(tx);
                        system.LocalNode.Tell(new LocalNode.Relay {
                            Inventory = tx
                        });
                        return(tx.ToJson());
                    }
                    else
                    {
                        return(context.ToJson());
                    }
                }

            case "submitblock":
            {
                Block             block  = _params[0].AsString().HexToBytes().AsSerializable <Block>();
                RelayResultReason reason = system.Blockchain.Ask <RelayResultReason>(block).Result;
                return(GetRelayResult(reason));
            }

            case "validateaddress":
            {
                JObject json = new JObject();
                UInt160 scriptHash;
                try
                {
                    scriptHash = _params[0].AsString().ToScriptHash();
                }
                catch
                {
                    scriptHash = null;
                }
                json["address"] = _params[0];
                json["isvalid"] = scriptHash != null;
                return(json);
            }

            default:
                throw new RpcException(-32601, "Method not found");
            }
        }
Esempio n. 26
0
        private bool OnSendCommand(string[] args)
        {
            if (args.Length < 4 || args.Length > 5)
            {
                Console.WriteLine("error");
                return(true);
            }
            if (Program.Wallet == null)
            {
                Console.WriteLine("You have to open the wallet first.");
                return(true);
            }
            using (SecureString password = ReadSecureString("password"))
            {
                if (password.Length == 0)
                {
                    Console.WriteLine("cancelled");
                    return(true);
                }
                if (!Program.Wallet.VerifyPassword(password))
                {
                    Console.WriteLine("Incorrect password");
                    return(true);
                }
            }
            UIntBase assetId;

            switch (args[1].ToLower())
            {
            case "pure":
            case "ans":
                assetId = Blockchain.GoverningToken.Hash;
                break;

            case "gas":
            case "anc":
                assetId = Blockchain.UtilityToken.Hash;
                break;

            default:
                assetId = UIntBase.Parse(args[1]);
                break;
            }
            UInt160     scriptHash = Wallet.ToScriptHash(args[2]);
            bool        isSendAll  = string.Equals(args[3], "all", StringComparison.OrdinalIgnoreCase);
            Transaction tx;

            if (isSendAll)
            {
                Coin[] coins = Program.Wallet.FindUnspentCoins().Where(p => p.Output.AssetId.Equals(assetId)).ToArray();
                tx = new ContractTransaction
                {
                    Attributes = new TransactionAttribute[0],
                    Inputs     = coins.Select(p => p.Reference).ToArray(),
                    Outputs    = new[]
                    {
                        new TransactionOutput
                        {
                            AssetId    = (UInt256)assetId,
                            Value      = coins.Sum(p => p.Output.Value),
                            ScriptHash = scriptHash
                        }
                    }
                };
            }
            else
            {
                AssetDescriptor descriptor = new AssetDescriptor(assetId);
                if (!BigDecimal.TryParse(args[3], descriptor.Decimals, out BigDecimal amount))
                {
                    Console.WriteLine("Incorrect Amount Format");
                    return(true);
                }
                Fixed8 fee = args.Length >= 5 ? Fixed8.Parse(args[4]) : Fixed8.Zero;
                tx = Program.Wallet.MakeTransaction(null, new[]
                {
                    new TransferOutput
                    {
                        AssetId    = assetId,
                        Value      = amount,
                        ScriptHash = scriptHash
                    }
                }, fee: fee);
                if (tx == null)
                {
                    Console.WriteLine("Insufficient funds");
                    return(true);
                }
            }
            ContractParametersContext context = new ContractParametersContext(tx);

            Program.Wallet.Sign(context);
            if (context.Completed)
            {
                tx.Scripts = context.GetScripts();
                Program.Wallet.SaveTransaction(tx);
                LocalNode.Relay(tx);
                Console.WriteLine($"TXID: {tx.Hash}");
            }
            else
            {
                Console.WriteLine("SignatureContext:");
                Console.WriteLine(context.ToString());
            }
            return(true);
        }
Esempio n. 27
0
        protected override JObject Process(string method, JArray _params)
        {
            switch (method)
            {
            //{"name":null,"version":"1.0","scrypt":{"n":16384,"r":8,"p":8},"accounts":[{"address":"AHGVqc2L3vbxG8N6t76oxg8ihdyxcqePB1","label":null,"isDefault":false,"lock":false,"key":"6PYMhaNsXjhGALn3XfEqwFLr3VsbCmgfr1WHMjaNgS5C9677L4KNoih46G","contract":{"script":"210331cef9faf71d85c4dd19911dd7d53815dc69056322f1db62a66df264e5f8ba8cac","parameters":[{"name":"signature","type":"Signature"}],"deployed":false},"extra":null},{"address":"ARBFVamaqvmyVjyN6P8V3tGeoZZJBZ7drP","label":null,"isDefault":false,"lock":false,"key":"6PYSMmydUaZCiYa6B8AgGJYDsXXfTmr1PdG27uWPkjtsdv4n3K2tbQ8WM1","contract":{"script":"2102ca41146dba006ef61e328e0735bdb46e76ee12f8feb94eec0f5cfb1bcf57ee17ac","parameters":[{"name":"signature","type":"Signature"}],"deployed":false},"extra":null},{"address":"AJ3uJEYBudv5ZFo2Eg6MFP1ZzimefzD8vZ","label":null,"isDefault":false,"lock":false,"key":"6PYWzN8pz45xxQu4wkQtn8GwvbfUhDS9iRBDgdLt5Vwd1RgkU6SAtuApuR","contract":{"script":"2103f4ca1a9ab97e8cdcd6349b72ff0914f5b70774a2c6927d4c0db1b2d733c696bcac","parameters":[{"name":"signature","type":"Signature"}],"deployed":false},"extra":null}],"extra":null}
            //将整个钱包的json作为一个串放进param
            // "{'jsonrpc': '2.0', 'method': 'openwallet', 'params': ["walllet-base64-json","password"],  'id': 1}"


            case "openwallet":
            {
                string oStr = Base64Decode(_params[0].AsString());
                //System.Console.WriteLine(_params[0].AsString());
                //System.Console.WriteLine(oStr);
                //JObject walletJson = _params[0];
                string password = Base64Decode(_params[1].AsString());

                string path = Directory.GetCurrentDirectory() + "\\" + "tmp.json";

                FileStream F = new FileStream("tmp.json", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                F.SetLength(0);
                StreamWriter sw = new StreamWriter(F);
                //sw.Write(walletJson.AsString());
                sw.Write(oStr);
                sw.Flush();
                sw.Close();

                JObject json = new JObject();

                NEP6Wallet nep6wallet = new NEP6Wallet(path);
                try
                {
                    nep6wallet.Unlock(password);
                }
                catch (CryptographicException)
                {
                    System.Console.WriteLine($"failed to open wallet \"{path}\"");
                    File.Delete(path);
                    throw new RpcException(-400, "Access denied");
                }

                Program.Wallet = nep6wallet;

                File.Delete(path);         //打开后删除钱包文件
                return("0");
            }

            case "closewallet":
            {
                //对当前打开的钱包做校验
                // if(Program.Wallet != null)
                // {
                //     Base64Encode
                // }



                Program.Wallet = null;
                return("0");
            }

            case "getapplicationlog":
            {
                UInt256 hash = UInt256.Parse(_params[0].AsString());
                string  path = Path.Combine(Settings.Default.Paths.ApplicationLogs, $"{hash}.json");
                return(File.Exists(path)
                            ? JObject.Parse(File.ReadAllText(path))
                            : throw new RpcException(-100, "Unknown transaction"));
            }

            case "getbalance":
                if (Program.Wallet == null)
                {
                    throw new RpcException(-400, "Access denied.");
                }
                else
                {
                    JObject json = new JObject();
                    switch (UIntBase.Parse(_params[0].AsString()))
                    {
                    case UInt160 asset_id_160:         //NEP-5 balance
                        json["balance"] = Program.Wallet.GetAvailable(asset_id_160).ToString();
                        break;

                    case UInt256 asset_id_256:         //Global Assets balance
                        IEnumerable <Coin> coins = Program.Wallet.GetCoins().Where(p => !p.State.HasFlag(CoinState.Spent) && p.Output.AssetId.Equals(asset_id_256));
                        json["balance"]   = coins.Sum(p => p.Output.Value).ToString();
                        json["confirmed"] = coins.Where(p => p.State.HasFlag(CoinState.Confirmed)).Sum(p => p.Output.Value).ToString();
                        break;
                    }
                    return(json);
                }

            case "listaddress":
                if (Program.Wallet == null)
                {
                    throw new RpcException(-400, "Access denied.");
                }
                else
                {
                    return(Program.Wallet.GetAccounts().Select(p =>
                    {
                        JObject account = new JObject();
                        account["address"] = p.Address;
                        account["haskey"] = p.HasKey;
                        account["label"] = p.Label;
                        account["watchonly"] = p.WatchOnly;
                        return account;
                    }).ToArray());
                }

            case "sendfrom":
                if (Program.Wallet == null)
                {
                    throw new RpcException(-400, "Access denied");
                }
                else
                {
                    UIntBase        assetId    = UIntBase.Parse(_params[0].AsString());
                    AssetDescriptor descriptor = new AssetDescriptor(assetId);
                    UInt160         from       = Wallet.ToScriptHash(_params[1].AsString());
                    UInt160         to         = Wallet.ToScriptHash(_params[2].AsString());
                    BigDecimal      value      = BigDecimal.Parse(_params[3].AsString(), descriptor.Decimals);
                    if (value.Sign <= 0)
                    {
                        throw new RpcException(-32602, "Invalid params");
                    }
                    Fixed8 fee = _params.Count >= 5 ? Fixed8.Parse(_params[4].AsString()) : Fixed8.Zero;
                    if (fee < Fixed8.Zero)
                    {
                        throw new RpcException(-32602, "Invalid params");
                    }
                    UInt160     change_address = _params.Count >= 6 ? Wallet.ToScriptHash(_params[5].AsString()) : null;
                    Transaction tx             = Program.Wallet.MakeTransaction(null, new[]
                    {
                        new TransferOutput
                        {
                            AssetId    = assetId,
                            Value      = value,
                            ScriptHash = to
                        }
                    }, from: from, change_address: change_address, fee: fee);
                    if (tx == null)
                    {
                        throw new RpcException(-300, "Insufficient funds");
                    }
                    ContractParametersContext context = new ContractParametersContext(tx);
                    Program.Wallet.Sign(context);
                    if (context.Completed)
                    {
                        tx.Scripts = context.GetScripts();
                        Program.Wallet.ApplyTransaction(tx);
                        LocalNode.Relay(tx);
                        return(tx.ToJson());
                    }
                    else
                    {
                        return(context.ToJson());
                    }
                }

            case "sendtoaddress":
                if (Program.Wallet == null)
                {
                    throw new RpcException(-400, "Access denied");
                }
                else
                {
                    UIntBase        assetId    = UIntBase.Parse(_params[0].AsString());
                    AssetDescriptor descriptor = new AssetDescriptor(assetId);
                    UInt160         scriptHash = Wallet.ToScriptHash(_params[1].AsString());
                    BigDecimal      value      = BigDecimal.Parse(_params[2].AsString(), descriptor.Decimals);
                    if (value.Sign <= 0)
                    {
                        throw new RpcException(-32602, "Invalid params");
                    }
                    Fixed8 fee = _params.Count >= 4 ? Fixed8.Parse(_params[3].AsString()) : Fixed8.Zero;
                    if (fee < Fixed8.Zero)
                    {
                        throw new RpcException(-32602, "Invalid params");
                    }
                    UInt160     change_address = _params.Count >= 5 ? Wallet.ToScriptHash(_params[4].AsString()) : null;
                    Transaction tx             = Program.Wallet.MakeTransaction(null, new[]
                    {
                        new TransferOutput
                        {
                            AssetId    = assetId,
                            Value      = value,
                            ScriptHash = scriptHash
                        }
                    }, change_address: change_address, fee: fee);
                    if (tx == null)
                    {
                        throw new RpcException(-300, "Insufficient funds");
                    }
                    ContractParametersContext context = new ContractParametersContext(tx);
                    Program.Wallet.Sign(context);
                    if (context.Completed)
                    {
                        tx.Scripts = context.GetScripts();
                        Program.Wallet.ApplyTransaction(tx);
                        LocalNode.Relay(tx);
                        return(tx.ToJson());
                    }
                    else
                    {
                        return(context.ToJson());
                    }
                }

            case "sendmany":
                if (Program.Wallet == null)
                {
                    throw new RpcException(-400, "Access denied");
                }
                else
                {
                    JArray to = (JArray)_params[0];
                    if (to.Count == 0)
                    {
                        throw new RpcException(-32602, "Invalid params");
                    }
                    TransferOutput[] outputs = new TransferOutput[to.Count];
                    for (int i = 0; i < to.Count; i++)
                    {
                        UIntBase        asset_id   = UIntBase.Parse(to[i]["asset"].AsString());
                        AssetDescriptor descriptor = new AssetDescriptor(asset_id);
                        outputs[i] = new TransferOutput
                        {
                            AssetId    = asset_id,
                            Value      = BigDecimal.Parse(to[i]["value"].AsString(), descriptor.Decimals),
                            ScriptHash = Wallet.ToScriptHash(to[i]["address"].AsString())
                        };
                        if (outputs[i].Value.Sign <= 0)
                        {
                            throw new RpcException(-32602, "Invalid params");
                        }
                    }
                    Fixed8 fee = _params.Count >= 2 ? Fixed8.Parse(_params[1].AsString()) : Fixed8.Zero;
                    if (fee < Fixed8.Zero)
                    {
                        throw new RpcException(-32602, "Invalid params");
                    }
                    UInt160     change_address = _params.Count >= 3 ? Wallet.ToScriptHash(_params[2].AsString()) : null;
                    Transaction tx             = Program.Wallet.MakeTransaction(null, outputs, change_address: change_address, fee: fee);
                    if (tx == null)
                    {
                        throw new RpcException(-300, "Insufficient funds");
                    }
                    ContractParametersContext context = new ContractParametersContext(tx);
                    Program.Wallet.Sign(context);
                    if (context.Completed)
                    {
                        tx.Scripts = context.GetScripts();
                        Program.Wallet.ApplyTransaction(tx);
                        LocalNode.Relay(tx);
                        return(tx.ToJson());
                    }
                    else
                    {
                        return(context.ToJson());
                    }
                }

            case "getnewaddress":
                if (Program.Wallet == null)
                {
                    throw new RpcException(-400, "Access denied");
                }
                else
                {
                    WalletAccount account = Program.Wallet.CreateAccount();
                    if (Program.Wallet is NEP6Wallet wallet)
                    {
                        wallet.Save();
                    }
                    return(account.Address);
                }

            case "dumpprivkey":
                if (Program.Wallet == null)
                {
                    throw new RpcException(-400, "Access denied");
                }
                else
                {
                    UInt160       scriptHash = Wallet.ToScriptHash(_params[0].AsString());
                    WalletAccount account    = Program.Wallet.GetAccount(scriptHash);
                    return(account.GetKey().Export());
                }

            case "invoke":
            case "invokefunction":
            case "invokescript":
                JObject result = base.Process(method, _params);
                if (Program.Wallet != null)
                {
                    InvocationTransaction tx = new InvocationTransaction
                    {
                        Version = 1,
                        Script  = result["script"].AsString().HexToBytes(),
                        Gas     = Fixed8.Parse(result["gas_consumed"].AsString())
                    };
                    tx.Gas -= Fixed8.FromDecimal(10);
                    if (tx.Gas < Fixed8.Zero)
                    {
                        tx.Gas = Fixed8.Zero;
                    }
                    tx.Gas = tx.Gas.Ceiling();
                    tx     = Program.Wallet.MakeTransaction(tx);
                    if (tx != null)
                    {
                        ContractParametersContext context = new ContractParametersContext(tx);
                        Program.Wallet.Sign(context);
                        if (context.Completed)
                        {
                            tx.Scripts = context.GetScripts();
                        }
                        else
                        {
                            tx = null;
                        }
                    }
                    result["tx"] = tx?.ToArray().ToHexString();
                }
                return(result);

            default:
                return(base.Process(method, _params));
            }
        }
Esempio n. 28
0
        private bool OnSendCommand(string[] args)
        {
            if (args.Length < 4 || args.Length > 5)
            {
                Console.WriteLine("error");
                return(true);
            }
            if (NoWallet())
            {
                return(true);
            }
            string password = ReadUserInput("password", true);

            if (password.Length == 0)
            {
                Console.WriteLine("cancelled");
                return(true);
            }
            if (!Program.Wallet.VerifyPassword(password))
            {
                Console.WriteLine("Incorrect password");
                return(true);
            }
            UInt160 assetId;

            switch (args[1].ToLower())
            {
            case "neo":
                assetId = NativeContract.NEO.Hash;
                break;

            case "gas":
                assetId = NativeContract.GAS.Hash;
                break;

            default:
                assetId = UInt160.Parse(args[1]);
                break;
            }
            UInt160         to = args[2].ToScriptHash();
            Transaction     tx;
            AssetDescriptor descriptor = new AssetDescriptor(assetId);

            if (!BigDecimal.TryParse(args[3], descriptor.Decimals, out BigDecimal amount) || amount.Sign <= 0)
            {
                Console.WriteLine("Incorrect Amount Format");
                return(true);
            }
            tx = Program.Wallet.MakeTransaction(null, new[]
            {
                new TransferOutput
                {
                    AssetId    = assetId,
                    Value      = amount,
                    ScriptHash = to
                }
            });

            if (tx == null)
            {
                Console.WriteLine("Insufficient funds");
                return(true);
            }

            ContractParametersContext context = new ContractParametersContext(tx);

            Program.Wallet.Sign(context);
            if (context.Completed)
            {
                tx.Witness = context.GetWitness();
                system.LocalNode.Tell(new LocalNode.Relay {
                    Inventory = tx
                });
                Console.WriteLine($"TXID: {tx.Hash}");
            }
            else
            {
                Console.WriteLine("SignatureContext:");
                Console.WriteLine(context.ToString());
            }

            return(true);
        }
Esempio n. 29
0
 private static void OnDownloadBegin(AssetDescriptor asset, string msg)
 {
     UpdateMessage(string.Format("{0} | {1}", asset.Name, msg));
 }
Esempio n. 30
0
        /// <summary>
        /// 发送一个包含订单信息的交易
        /// </summary>
        /// <param name="_params[0]">订单信息</param>
        /// <param name="_params[1]">资产 ID</param>
        /// <param name="_params[2]">收款地址</param>
        /// <param name="_params[3]">转账金额</param>
        /// <param name="_params[4]">手续费,可选参数,默认为 0</param>
        /// <param name="_params[5]">找零地址,可选参数,默认为钱包中第一个标准地址</param>
        /// <param name="_params[6]">bhp手续费地址,可选参数。(转账资产包含BHP时,此参数无效)</param>
        /// <returns>交易</returns>
        private JObject SendToAddressOrder(JArray _params)
        {
            if (wallet == null || walletTimeLock.IsLocked())
            {
                throw new RpcException(-400, "Access denied");
            }
            else
            {
                string remarks = _params[0].AsString();
                List <TransactionAttribute> attributes = new List <TransactionAttribute>();
                using (ScriptBuilder sb = new ScriptBuilder())
                {
                    sb.EmitPush(remarks);
                    attributes.Add(new TransactionAttribute
                    {
                        Usage = TransactionAttributeUsage.Description,
                        Data  = sb.ToArray()
                    });
                }
                UIntBase        assetId    = UIntBase.Parse(_params[1].AsString());
                AssetDescriptor descriptor = new AssetDescriptor(assetId);
                UInt160         scriptHash = _params[2].AsString().ToScriptHash();
                BigDecimal      value      = BigDecimal.Parse(_params[3].AsString(), descriptor.Decimals);
                if (value.Sign <= 0)
                {
                    throw new RpcException(-32602, "Invalid params");
                }
                Fixed8 fee = _params.Count >= 5 ? Fixed8.Parse(_params[4].AsString()) : Fixed8.Zero;
                if (fee < Fixed8.Zero)
                {
                    throw new RpcException(-32602, "Invalid params");
                }
                UInt160 change_address = _params.Count >= 6 ? _params[5].AsString().ToScriptHash() : null;
                UInt160 fee_address    = _params.Count >= 7 ? _params[6].AsString().ToScriptHash() : null;
                if (assetId.Equals(Blockchain.GoverningToken.Hash))
                {
                    fee_address = null;
                }
                Transaction tx = wallet.MakeTransaction(attributes, new[]
                {
                    new TransferOutput
                    {
                        AssetId    = assetId,
                        Value      = value,
                        ScriptHash = scriptHash
                    }
                }, fee_address: fee_address, change_address: change_address, fee: fee);
                if (tx == null)
                {
                    throw new RpcException(-300, "Insufficient funds");
                }
                ContractParametersContext context = new ContractParametersContext(tx);
                wallet.Sign(context);
                if (context.Completed)
                {
                    tx.Witnesses = context.GetWitnesses();

                    if (tx.Size > Transaction.MaxTransactionSize)
                    {
                        throw new RpcException(-301, "The size of the free transaction must be less than 102400 bytes");
                    }

                    wallet.ApplyTransaction(tx);
                    system.LocalNode.Tell(new LocalNode.Relay {
                        Inventory = tx
                    });
                    return(tx.ToJson());
                }
                else
                {
                    return(context.ToJson());
                }
            }
        }