Пример #1
0
        private void AddAccount(WalletAccount account)
        {
            AccountControl accountFrm = new AccountControl(account);

            accountFrm.Parent = panel2;
            accountFrm.Dock   = DockStyle.Top;
            accountFrm.Show();

            foreach (string asset in Settings.Default.NEP5Watched)
            {
                AssetControl assetControl = new AssetControl(UInt160.Parse(asset), account);
                if (assetControl.IsShow)
                {
                    assetControl.Parent = panel4;
                    assetControl.Dock   = DockStyle.Top;
                }
                else
                {
                    assetControl.Dispose();
                }
            }
        }
Пример #2
0
        public void Reset(Wallet wallet)
        {
            State             = ConsensusState.Initial;
            PrevHash          = Blockchain.Default.CurrentBlockHash;
            BlockIndex        = Blockchain.Default.Height + 1;
            ViewNumber        = 0;
            Validators        = Blockchain.Default.GetValidators();
            MyIndex           = -1;
            PrimaryIndex      = BlockIndex % (uint)Validators.Length;
            TransactionHashes = null;
            Signatures        = new byte[Validators.Length][];
            ExpectedView      = new byte[Validators.Length];
            KeyPair           = null;
            WalletAccount account = wallet.GetAccount(Blockchain.GetConsensusAddress(Validators));

            if (account?.HasKey == true)
            {
                KeyPair = account.GetKey();
                MyIndex = Array.IndexOf(Validators, KeyPair.PublicKey);
            }
            _header = null;
        }
Пример #3
0
 public static bool Create(string walletPath, out WalletAccount walletAccount)
 {
     walletAccount = null;
     try
     {
         NEP6Wallet wallet = new NEP6Wallet(walletPath);
         wallet.Unlock(_password);
         walletAccount = wallet.CreateAccount();
         wallet.Save();
         if (ActiveWallet != null)
         {
             ActiveWallet.Dispose();
         }
         ActiveWallet = wallet;
         NeoStudio.Init.ChangeWallet(wallet);
         return(true);
     }
     catch
     {
         return(false);
     }
 }
Пример #4
0
        public void TestAddCount()
        {
            uut.CreateAccount(testScriptHash);
            Assert.IsTrue(uut.Contains(testScriptHash));
            WalletAccount account = uut.GetAccount(testScriptHash);

            Assert.IsTrue(account.WatchOnly);
            Assert.IsFalse(account.HasKey);
            uut.Unlock("123");
            uut.CreateAccount(keyPair.PrivateKey);
            account = uut.GetAccount(testScriptHash);
            Assert.IsFalse(account.WatchOnly);
            Assert.IsTrue(account.HasKey);
            uut.CreateAccount(testScriptHash);
            account = uut.GetAccount(testScriptHash);
            Assert.IsFalse(account.WatchOnly);
            Assert.IsFalse(account.HasKey);
            uut.CreateAccount(keyPair.PrivateKey);
            account = uut.GetAccount(testScriptHash);
            Assert.IsFalse(account.WatchOnly);
            Assert.IsTrue(account.HasKey);
        }
Пример #5
0
        private void OnCreateAddressCommand(ushort count = 1)
        {
            if (NoWallet())
            {
                return;
            }
            string path = "address.txt";

            if (File.Exists(path))
            {
                if (!ReadUserInput($"The file '{path}' already exists, do you want to overwrite it? (yes|no)", false).IsYes())
                {
                    return;
                }
            }

            List <string> addresses = new List <string>();

            using (var percent = new ConsolePercent(0, count))
            {
                Parallel.For(0, count, (i) =>
                {
                    WalletAccount account = CurrentWallet.CreateAccount();
                    lock (addresses)
                    {
                        addresses.Add(account.Address);
                        percent.Value++;
                    }
                });
            }

            if (CurrentWallet is NEP6Wallet wallet)
            {
                wallet.Save();
            }

            Console.WriteLine($"Export addresses to {path}");
            File.WriteAllLines(path, addresses);
        }
Пример #6
0
        public void TestMakeTransaction2()
        {
            MyWallet wallet = new MyWallet();
            Action   action = () => wallet.MakeTransaction(new byte[] { }, UInt160.Zero, new TransactionAttribute[] { });

            action.ShouldThrow <ArgumentException>();

            Contract      contract = Contract.Create(new ContractParameterType[] { ContractParameterType.Boolean }, new byte[] { 1 });
            WalletAccount account  = wallet.CreateAccount(contract, glkey.PrivateKey);

            account.Lock = false;

            // Fake balance
            var snapshot = store.GetSnapshot();
            var key      = NativeContract.LINK.CreateStorageKey(20, account.ScriptHash);
            var entry    = snapshot.Storages.GetAndChange(key, () => new StorageItem
            {
                Value = new Tlp5AccountState().ToByteArray()
            });

            entry.Value = new Tlp5AccountState()
            {
                Balance = 1000000 * NativeContract.LINK.Factor
            }
            .ToByteArray();

            var tx = wallet.MakeTransaction(new byte[] { }, account.ScriptHash, new TransactionAttribute[] { });

            tx.Should().NotBeNull();

            tx = wallet.MakeTransaction(new byte[] { }, null, new TransactionAttribute[] { });
            tx.Should().NotBeNull();

            entry.Value = new TrustToken.AccountState()
            {
                Balance = 0
            }
            .ToByteArray();
        }
Пример #7
0
        private void AddMiningTransaction(Wallet wallet, uint blockIndex, List <TransactionOutput> outputs, List <TransactionAttribute> attributes)
        {
            MiningOutput miningOutput = new MiningOutput
            {
                AssetId    = Blockchain.GoverningToken.Hash,
                Value      = MiningSubsidy.GetMiningSubsidy(blockIndex),
                ScriptHash = MiningParams.PoSAddress.Length > 0 ? MiningParams.PoSAddress[blockIndex % (uint)MiningParams.PoSAddress.Length].ToScriptHash() : wallet.GetChangeAddress()
            };

            TransactionOutput output = new TransactionOutput
            {
                AssetId    = miningOutput.AssetId,
                Value      = miningOutput.Value,
                ScriptHash = miningOutput.ScriptHash
            };

            byte[] signatureOfMining = null;

            //Signature
            WalletAccount account = wallet.GetAccount(wallet.GetChangeAddress());

            if (account?.HasKey == true)
            {
                byte[]  hashDataOfMining = miningOutput.GetHashData();
                KeyPair key = account.GetKey();
                signatureOfMining = Crypto.Default.Sign(hashDataOfMining, key.PrivateKey, key.PublicKey.EncodePoint(false).Skip(1).ToArray());
            }

            if (signatureOfMining != null)
            {
                attributes.Add(new TransactionAttribute
                {
                    Usage = TransactionAttributeUsage.MinerSignature,
                    Data  = signatureOfMining
                });

                outputs.Add(output);
            }
        }
Пример #8
0
        public void TestGetAvailable()
        {
            MyWallet      wallet   = new MyWallet();
            Contract      contract = Contract.Create(new ContractParameterType[] { ContractParameterType.Boolean }, new byte[] { 1 });
            WalletAccount account  = wallet.CreateAccount(contract, glkey.PrivateKey);

            account.Lock = false;

            // Fake balance
            var snapshot = TestBlockchain.GetTestSnapshot();
            var key      = NativeContract.GAS.CreateStorageKey(20, account.ScriptHash);
            var entry    = snapshot.GetAndChange(key, () => new StorageItem(new AccountState()));

            entry.GetInteroperable <AccountState>().Balance = 10000 * NativeContract.GAS.Factor;
            snapshot.Commit();

            wallet.GetAvailable(snapshot, NativeContract.GAS.Hash).Should().Be(new BigDecimal(new BigInteger(1000000000000M), 8));

            entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState()));
            entry.GetInteroperable <AccountState>().Balance = 0;
            snapshot.Commit();
        }
Пример #9
0
        private bool OnImportMultisigAddress(string[] args)
        {
            TR.Enter();
            if (NoWallet())
            {
                return(TR.Exit(true));
            }

            if (args.Length < 5)
            {
                Console.WriteLine("Error. Use at least 2 public keys to create a multisig address.");
                return(TR.Exit(true));
            }

            int m = int.Parse(args[2]);
            int n = args.Length - 3;

            if (m < 1 || m > n || n > 1024)
            {
                Console.WriteLine("Error. Invalid parameters.");
                return(TR.Exit(true));
            }

            ECPoint[] publicKeys = args.Skip(3).Select(p => ECPoint.Parse(p, ECCurve.Secp256r1)).ToArray();

            Contract multiSignContract = Contract.CreateMultiSigContract(m, publicKeys);
            KeyPair  keyPair           = Program.Wallet.GetAccounts().FirstOrDefault(p => p.HasKey && publicKeys.Contains(p.GetKey().PublicKey))?.GetKey();

            WalletAccount account = Program.Wallet.CreateAccount(multiSignContract, keyPair);

            if (Program.Wallet is NEP6Wallet wallet)
            {
                wallet.Save();
            }

            Console.WriteLine("Multisig. Addr.: " + multiSignContract.Address);

            return(TR.Exit(true));
        }
Пример #10
0
        private bool OnCreateWalletCommand(string[] args)
        {
            if (args.Length < 3)
            {
                Console.WriteLine("error");
                return(true);
            }
            string path = args[2];

            if (Path.GetExtension(path) == ".db3")
            {
                Console.WriteLine("Wallet files in db3 format are not supported, please use a .json file extension.");
                return(true);
            }
            string password = ReadPassword("password");

            if (password.Length == 0)
            {
                Console.WriteLine("cancelled");
                return(true);
            }
            string password2 = ReadPassword("password");

            if (password != password2)
            {
                Console.WriteLine("error");
                return(true);
            }
            NEP6Wallet wallet = new NEP6Wallet(path);

            wallet.Unlock(password);
            WalletAccount account = wallet.CreateAccount();

            wallet.Save();
            Program.Wallet = wallet;
            Console.WriteLine($"address: {account.Address}");
            Console.WriteLine($" pubkey: {account.GetKey().PublicKey.EncodePoint(true).ToHexString()}");
            return(true);
        }
Пример #11
0
        private void AddAccount(WalletAccount account, bool selected = false)
        {
            ListViewItem item = listView1.Items[account.Address];

            if (item != null)
            {
                if (!account.WatchOnly && ((WalletAccount)item.Tag).WatchOnly)
                {
                    listView1.Items.Remove(item);
                    item = null;
                }
            }
            if (item == null)
            {
                string groupName = account.WatchOnly ? "watchOnlyGroup" : account.Contract.Script.IsSignatureContract() ? "standardContractGroup" : "nonstandardContractGroup";
                item = listView1.Items.Add(new ListViewItem(new[]
                {
                    new ListViewItem.ListViewSubItem
                    {
                        Name = "address",
                        Text = account.Address
                    },
                    new ListViewItem.ListViewSubItem
                    {
                        Name = NativeContract.NEO.Symbol
                    },
                    new ListViewItem.ListViewSubItem
                    {
                        Name = NativeContract.GAS.Symbol
                    }
                }, -1, listView1.Groups[groupName])
                {
                    Name = account.Address,
                    Tag  = account
                });
            }
            item.Selected = selected;
        }
Пример #12
0
        private bool OnCreateAddressCommand(string[] args)
        {
            if (Program.Wallet == null)
            {
                Console.WriteLine("You have to open the wallet first.");
                return(true);
            }
            if (args.Length > 3)
            {
                Console.WriteLine("error");
                return(true);
            }
            ushort count = 1;

            if (args.Length >= 3)
            {
                count = ushort.Parse(args[2]);
            }
            List <string> addresses = new List <string>();

            for (int i = 1; i <= count; i++)
            {
                WalletAccount account = Program.Wallet.CreateAccount();
                addresses.Add(account.Address);
                Console.SetCursorPosition(0, Console.CursorTop);
                Console.Write($"[{i}/{count}]");
            }
            if (Program.Wallet is NEP6Wallet wallet)
            {
                wallet.Save();
            }
            Console.WriteLine();
            string path = "address.txt";

            Console.WriteLine($"export addresses to {path}");
            File.WriteAllLines(path, addresses);
            return(true);
        }
Пример #13
0
        private void 多方签名MToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using CreateMultiSigContractDialog dialog = new CreateMultiSigContractDialog();
            if (dialog.ShowDialog() != DialogResult.OK)
            {
                return;
            }
            Contract contract = dialog.GetContract();

            if (contract == null)
            {
                MessageBox.Show(Strings.AddContractFailedMessage);
                return;
            }
            WalletAccount account = Service.CurrentWallet.CreateAccount(contract, dialog.GetKey());

            if (Service.CurrentWallet is NEP6Wallet wallet)
            {
                wallet.Save();
            }
            listView1.SelectedIndices.Clear();
            AddAccount(account, true);
        }
Пример #14
0
        private void SetAccountInfo(WalletAccount account)
        {
            if (account == null)
            {
                return;
            }

            var key = account.GetKey();

            this.Address      = account.Address;
            this.PublicKeyHex = key.PublicKey.EncodePoint(true).ToHexString();
            using (key.Decrypt())
            {
                this.PrivateKeyHex = key.PrivateKey.ToHexString();
            }
            this.PrivateKeyWif = key.Export();

            // Update properties
            RaisePropertyChanged(nameof(this.Address));
            RaisePropertyChanged(nameof(this.PublicKeyHex));
            RaisePropertyChanged(nameof(this.PrivateKeyHex));
            RaisePropertyChanged(nameof(this.PrivateKeyWif));
        }
Пример #15
0
 public VerificationContext(Wallet wallet, uint index)
 {
     this.wallet = wallet;
     Retries     = 0;
     myIndex     = -1;
     rootIndex   = index;
     verifiers   = NativeContract.RoleManagement.GetDesignatedByRole(StatePlugin.System.StoreView, Role.StateValidator, index);
     if (wallet is null)
     {
         return;
     }
     for (int i = 0; i < verifiers.Length; i++)
     {
         WalletAccount account = wallet.GetAccount(verifiers[i]);
         if (account?.HasKey != true)
         {
             continue;
         }
         myIndex = i;
         keyPair = account.GetKey();
         break;
     }
 }
Пример #16
0
 private void lockToolStripMenuItem_Click(object sender, EventArgs e)
 {
     using (CreateLockAccountDialog dialog = new CreateLockAccountDialog())
     {
         if (dialog.ShowDialog() != DialogResult.OK)
         {
             return;
         }
         Contract contract = dialog.GetContract();
         if (contract == null)
         {
             MessageBox.Show(LanHelper.LocalLanguage("Failed to add smart contract, corresponding private key missing in this wallet."));
             return;
         }
         WalletAccount account = Program.CurrentWallet.CreateAccount(contract, dialog.GetKey());
         if (Program.CurrentWallet is NEP6Wallet wallet)
         {
             wallet.Save();
         }
         listView1.SelectedIndices.Clear();
         AddAccount(account, true);
     }
 }
Пример #17
0
        public void TestGetBalance()
        {
            MyWallet      wallet   = new MyWallet();
            Contract      contract = Contract.Create(new ContractParameterType[] { ContractParameterType.Boolean }, new byte[] { 1 });
            WalletAccount account  = wallet.CreateAccount(contract, glkey.PrivateKey);

            account.Lock = false;

            // Fake balance
            var snapshot = Blockchain.Singleton.GetSnapshot();
            var key      = NativeContract.GAS.CreateStorageKey(20, account.ScriptHash);
            var entry    = snapshot.Storages.GetAndChange(key, () => new StorageItem(new Nep5AccountState()));

            entry.GetInteroperable <Nep5AccountState>().Balance = 10000 * NativeContract.GAS.Factor;
            snapshot.Commit();

            wallet.GetBalance(UInt160.Zero, new UInt160[] { account.ScriptHash }).Should().Be(new BigDecimal(0, 0));
            wallet.GetBalance(NativeContract.GAS.Hash, new UInt160[] { account.ScriptHash }).Should().Be(new BigDecimal(1000000000000, 8));

            entry = snapshot.Storages.GetAndChange(key, () => new StorageItem(new Nep5AccountState()));
            entry.GetInteroperable <Nep5AccountState>().Balance = 0;
            snapshot.Commit();
        }
Пример #18
0
        private void TransactAction(WalletAccount target, Account account, int value)
        {
            Program.CurrentWallet = account.Wallet;
            int curWalletAmount = int.Parse(Program.CurrentWallet.GetAvailable(Blockchain.GoverningToken.Hash).ToString());

            TransactionOutput[] outputs = new TransactionOutput[1];

            outputs[0] = new TransactionOutput
            {
                AssetId    = Blockchain.GoverningToken.Hash,
                ScriptHash = Wallet.ToScriptHash(target.Address),
                Value      = Fixed8.Parse(value.ToString())
            };

            if (curWalletAmount >= value)
            {
                TransactProcess(outputs, Program.CurrentWallet);
            }
            else
            {
                Thread.Sleep(16000);
            }
        }
Пример #19
0
        private void OnRegisterCandidateCommand(UInt160 account)
        {
            var testGas = NativeContract.NEO.GetRegisterPrice(NeoSystem.StoreView) + (BigInteger)Math.Pow(10, NativeContract.GAS.Decimals) * 10;

            if (NoWallet())
            {
                Console.WriteLine("Need open wallet!");
                return;
            }

            WalletAccount currentAccount = CurrentWallet.GetAccount(account);

            if (currentAccount == null)
            {
                Console.WriteLine("This address isn't in your wallet!");
                return;
            }
            else
            {
                if (currentAccount.Lock || currentAccount.WatchOnly)
                {
                    Console.WriteLine("Locked or WatchOnly address.");
                    return;
                }
            }

            ECPoint publicKey = currentAccount?.GetKey()?.PublicKey;

            byte[] script;
            using (ScriptBuilder scriptBuilder = new ScriptBuilder())
            {
                scriptBuilder.EmitDynamicCall(NativeContract.NEO.Hash, "registerCandidate", publicKey);
                script = scriptBuilder.ToArray();
            }

            SendTransaction(script, account, (long)testGas);
        }
Пример #20
0
        private void OnRegisterCandidateCommand(UInt160 account, decimal maxGas = RegisterGas)
        {
            var gas = new BigDecimal(maxGas, NativeContract.GAS.Decimals);

            if (NoWallet())
            {
                Console.WriteLine("Need open wallet!");
                return;
            }

            WalletAccount currentAccount = CurrentWallet.GetAccount(account);

            if (currentAccount == null)
            {
                Console.WriteLine("This address isn't in your wallet!");
                return;
            }
            else
            {
                if (currentAccount.Lock || currentAccount.WatchOnly)
                {
                    Console.WriteLine("Locked or WatchOnly address.");
                    return;
                }
            }

            ECPoint publicKey = currentAccount?.GetKey()?.PublicKey;

            byte[] script;
            using (ScriptBuilder scriptBuilder = new ScriptBuilder())
            {
                scriptBuilder.EmitDynamicCall(NativeContract.NEO.Hash, "registerCandidate", publicKey);
                script = scriptBuilder.ToArray();
            }

            SendTransaction(script, account, (long)gas.Value);
        }
Пример #21
0
 public void Reset(byte viewNumber)
 {
     if (viewNumber == 0)
     {
         Snapshot?.Dispose();
         Snapshot = Blockchain.Singleton.GetSnapshot();
         Block    = new Block
         {
             PrevHash      = Snapshot.CurrentBlockHash,
             Index         = Snapshot.Height + 1,
             NextConsensus = Blockchain.GetConsensusAddress(
                 NativeContract.NEO.ShouldRefreshCommittee(Snapshot.Height + 1) ?
                 NativeContract.NEO.ComputeNextBlockValidators(Snapshot) :
                 NativeContract.NEO.GetNextBlockValidators(Snapshot))
         };
         var pv = Validators;
         Validators = NativeContract.NEO.GetNextBlockValidators(Snapshot);
         if (_witnessSize == 0 || (pv != null && pv.Length != Validators.Length))
         {
             // Compute the expected size of the witness
             using (ScriptBuilder sb = new ScriptBuilder())
             {
                 for (int x = 0; x < M; x++)
                 {
                     sb.EmitPush(new byte[64]);
                 }
                 _witnessSize = new Witness
                 {
                     InvocationScript   = sb.ToArray(),
                     VerificationScript = Contract.CreateMultiSigRedeemScript(M, Validators)
                 }.Size;
             }
         }
         MyIndex                = -1;
         ChangeViewPayloads     = new ExtensiblePayload[Validators.Length];
         LastChangeViewPayloads = new ExtensiblePayload[Validators.Length];
         CommitPayloads         = new ExtensiblePayload[Validators.Length];
         if (ValidatorsChanged || LastSeenMessage is null)
         {
             var previous_last_seen_message = LastSeenMessage;
             LastSeenMessage = new Dictionary <ECPoint, uint>();
             foreach (var validator in Validators)
             {
                 if (previous_last_seen_message != null && previous_last_seen_message.TryGetValue(validator, out var value))
                 {
                     LastSeenMessage[validator] = value;
                 }
                 else
                 {
                     LastSeenMessage[validator] = Snapshot.Height;
                 }
             }
         }
         keyPair = null;
         for (int i = 0; i < Validators.Length; i++)
         {
             WalletAccount account = wallet?.GetAccount(Validators[i]);
             if (account?.HasKey != true)
             {
                 continue;
             }
             MyIndex = i;
             keyPair = account.GetKey();
             break;
         }
         cachedMessages = new Dictionary <UInt256, ConsensusMessage>();
     }
     else
     {
         for (int i = 0; i < LastChangeViewPayloads.Length; i++)
         {
             if (GetMessage <ChangeView>(ChangeViewPayloads[i])?.NewViewNumber >= viewNumber)
             {
                 LastChangeViewPayloads[i] = ChangeViewPayloads[i];
             }
             else
             {
                 LastChangeViewPayloads[i] = null;
             }
         }
     }
     ViewNumber          = viewNumber;
     Block.ConsensusData = new ConsensusData
     {
         PrimaryIndex = GetPrimaryIndex(viewNumber)
     };
     Block.MerkleRoot    = null;
     Block.Timestamp     = 0;
     Block.Transactions  = null;
     TransactionHashes   = null;
     PreparationPayloads = new ExtensiblePayload[Validators.Length];
     if (MyIndex >= 0)
     {
         LastSeenMessage[Validators[MyIndex]] = Block.Index;
     }
 }
Пример #22
0
        private bool OnCreateWalletCommand(string[] args)
        {
            if (args.Length < 3)
            {
                Console.WriteLine("error");
                return(true);
            }
            if (system.RpcServer != null &&
                ReadUserInput("Warning: Opening the wallet with RPC turned on could result in asset loss. Are you sure you want to do this? (yes|no)", false)?.ToLowerInvariant() != "yes")
            {
                return(true);
            }
            string path     = args[2];
            string password = ReadUserInput("password", true);

            if (password.Length == 0)
            {
                Console.WriteLine("cancelled");
                return(true);
            }
            string password2 = ReadUserInput("password", true);

            if (password != password2)
            {
                Console.WriteLine("error");
                return(true);
            }
            switch (Path.GetExtension(path))
            {
            case ".db3":
            {
                Program.Wallet = UserWallet.Create(path, password);
                WalletAccount account = Program.Wallet.CreateAccount();
                Console.WriteLine($"address: {account.Address}");
                Console.WriteLine($" pubkey: {account.GetKey().PublicKey.EncodePoint(true).ToHexString()}");
                if (system.RpcServer != null)
                {
                    system.RpcServer.Wallet = Program.Wallet;
                }
            }
            break;

            case ".json":
            {
                NEP6Wallet wallet = new NEP6Wallet(path);
                wallet.Unlock(password);
                WalletAccount account = wallet.CreateAccount();
                wallet.Save();
                Program.Wallet = wallet;
                Console.WriteLine($"address: {account.Address}");
                Console.WriteLine($" pubkey: {account.GetKey().PublicKey.EncodePoint(true).ToHexString()}");
                if (system.RpcServer != null)
                {
                    system.RpcServer.Wallet = Program.Wallet;
                }
            }
            break;

            default:
                Console.WriteLine("Wallet files in that format are not supported, please use a .json or .db3 file extension.");
                break;
            }
            return(true);
        }
Пример #23
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");
            }
        }
Пример #24
0
        private bool OnCreateWalletCommand(string[] args)
        {
            if (args.Length < 2)
            {
                Console.WriteLine("error");
                return(true);
            }

            //if (args.Length == 2)
            //{
            //    Console.WriteLine("功能正在开发中...");
            //    return true;
            //}

            string path = args[2];
            //string password = "";
            // 创建账号去掉密码 2018-04-11 TNT
            string password = ReadPassword("password");

            if (password.Length == 0)
            {
                Console.WriteLine("cancelled");
                return(true);
            }
            string password2 = ReadPassword("password");

            if (password != password2)
            {
                Console.WriteLine("error");
                return(true);
            }
            switch (Path.GetExtension(path))
            {
            case ".db3":
            {
                Program.Wallet = UserWallet.Create(path, password);
                WalletAccount account = Program.Wallet.CreateAccount();
                //Console.WriteLine($"address: {account.Address}");
                //Console.WriteLine($" pubkey: {account.GetKey().PublicKey.EncodePoint(true).ToHexString()}");
                PrintAccountInfo(account);
            }
            break;

            case ".json":
            {
                NEP6Wallet wallet = new NEP6Wallet(path);
                wallet.Unlock(password); // 添加锁定密码
                WalletAccount account = wallet.CreateAccount();
                wallet.Save();           // 保存到 文件中
                Program.Wallet = wallet;
                //Console.WriteLine($"address: {account.Address}");
                //Console.WriteLine($" pubkey: {account.GetKey().PublicKey.EncodePoint(true).ToHexString()}");
                PrintAccountInfo(account);
            }
            break;

            default:
                Console.WriteLine("Wallet files in that format are not supported, please use a .json or .db3 file extension.");
                break;
            }
            return(true);
        }
Пример #25
0
        private bool OnImportKeyCommand(string[] args)
        {
            if (args.Length > 3)
            {
                Console.WriteLine("error");
                return(true);
            }
            byte[] prikey = null;
            try
            {
                prikey = Wallet.GetPrivateKeyFromWIF(args[2]);
            }
            catch (FormatException) { }
            if (prikey == null)
            {
                var file = new FileInfo(args[2]);

                if (!file.Exists)
                {
                    Console.WriteLine($"Error: File '{file.FullName}' doesn't exists");
                    return(true);
                }

                if (file.Length > 1024 * 1024)
                {
                    if (ReadUserInput($"The file '{file.FullName}' is too big, do you want to continue? (yes|no)", false)?.ToLowerInvariant() != "yes")
                    {
                        return(true);
                    }
                }

                string[] lines = File.ReadAllLines(args[2]);
                for (int i = 0; i < lines.Length; i++)
                {
                    if (lines[i].Length == 64)
                    {
                        prikey = lines[i].HexToBytes();
                    }
                    else
                    {
                        prikey = Wallet.GetPrivateKeyFromWIF(lines[i]);
                    }
                    Program.Wallet.CreateAccount(prikey);
                    Array.Clear(prikey, 0, prikey.Length);
                    Console.SetCursorPosition(0, Console.CursorTop);
                    Console.Write($"[{i + 1}/{lines.Length}]");
                }
                Console.WriteLine();
            }
            else
            {
                WalletAccount account = Program.Wallet.CreateAccount(prikey);
                Array.Clear(prikey, 0, prikey.Length);
                Console.WriteLine($"address: {account.Address}");
                Console.WriteLine($" pubkey: {account.GetKey().PublicKey.EncodePoint(true).ToHexString()}");
            }
            if (Program.Wallet is NEP6Wallet wallet)
            {
                wallet.Save();
            }
            return(true);
        }
Пример #26
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));
            }
        }
Пример #27
0
        public void TestMakeTransaction1()
        {
            MyWallet      wallet   = new MyWallet();
            Contract      contract = Contract.Create(new ContractParameterType[] { ContractParameterType.Boolean }, new byte[] { 1 });
            WalletAccount account  = wallet.CreateAccount(contract, glkey.PrivateKey);

            account.Lock = false;

            Action action = () => wallet.MakeTransaction(new TransferOutput[]
            {
                new TransferOutput()
                {
                    AssetId    = NativeContract.GAS.Hash,
                    ScriptHash = account.ScriptHash,
                    Value      = new BigDecimal(1, 8)
                }
            }, UInt160.Zero);

            action.Should().Throw <ArgumentException>();

            action = () => wallet.MakeTransaction(new TransferOutput[]
            {
                new TransferOutput()
                {
                    AssetId    = NativeContract.GAS.Hash,
                    ScriptHash = account.ScriptHash,
                    Value      = new BigDecimal(1, 8)
                }
            }, account.ScriptHash);
            action.Should().Throw <InvalidOperationException>();

            action = () => wallet.MakeTransaction(new TransferOutput[]
            {
                new TransferOutput()
                {
                    AssetId    = UInt160.Zero,
                    ScriptHash = account.ScriptHash,
                    Value      = new BigDecimal(1, 8)
                }
            }, account.ScriptHash);
            action.Should().Throw <InvalidOperationException>();

            // Fake balance
            var snapshot = Blockchain.Singleton.GetSnapshot();
            var key      = NativeContract.GAS.CreateStorageKey(20, account.ScriptHash);
            var entry1   = snapshot.Storages.GetAndChange(key, () => new StorageItem
            {
                Value = new Nep5AccountState().ToByteArray()
            });

            entry1.Value = new Nep5AccountState()
            {
                Balance = 10000 * NativeContract.GAS.Factor
            }
            .ToByteArray();

            key = NativeContract.NEO.CreateStorageKey(20, account.ScriptHash);
            var entry2 = snapshot.Storages.GetAndChange(key, () => new StorageItem
            {
                Value = new Nep5AccountState().ToByteArray()
            });

            entry2.Value = new NeoToken.AccountState()
            {
                Balance = 10000 * NativeContract.NEO.Factor
            }
            .ToByteArray();

            snapshot.Commit();

            var tx = wallet.MakeTransaction(new TransferOutput[]
            {
                new TransferOutput()
                {
                    AssetId    = NativeContract.GAS.Hash,
                    ScriptHash = account.ScriptHash,
                    Value      = new BigDecimal(1, 8)
                }
            });

            tx.Should().NotBeNull();

            tx = wallet.MakeTransaction(new TransferOutput[]
            {
                new TransferOutput()
                {
                    AssetId    = NativeContract.NEO.Hash,
                    ScriptHash = account.ScriptHash,
                    Value      = new BigDecimal(1, 8)
                }
            });
            tx.Should().NotBeNull();

            entry1.Value = new Nep5AccountState()
            {
                Balance = 0
            }
            .ToByteArray();
            entry2.Value = new NeoToken.AccountState()
            {
                Balance = 0
            }
            .ToByteArray();
            snapshot.Commit();
        }
Пример #28
0
 public void AddAccount(WalletAccount account)
 {
     accounts.Add(account.ScriptHash, account);
 }
Пример #29
0
        public async Task <User> Handle(RegisterUserCommand request, CancellationToken cancellationToken)
        {
            var entity = _context.Users.SingleOrDefault(b => b.Email == request.Email);

            if (entity != null)
            {
                entity.statusCode = SharedStatusCodes.Exists;
                return(entity);
            }

            // Create User Entity
            User user_entity = new User
            {
                CountryID    = request.CountryID,
                FirstName    = request.FirstName,
                LastName     = request.LastName,
                Email        = request.Email,
                Phone        = request.Phone,
                Password     = request.Password,
                DateOfBirth  = request.DateOfBirth,
                AddressLine1 = request.AddressLine1,
                AddressLine2 = request.AddressLine2,
                IsActive     = false
            };

            _context.Users.Add(user_entity);

            try
            {
                if (await _context.SaveChangesAsync(cancellationToken) > 0)
                {
                    try
                    {
                        _context.Entry(user_entity).GetDatabaseValues();

                        // Create WalletAccount Entity
                        var defaultWalletCategory = new WalletAccountCategory().GetWalletAccountCategory(_context);

                        WalletAccount wallet_account_entity = new WalletAccount
                        {
                            UserID     = user_entity.ID,
                            CurrencyID = request.CurrencyID,
                            WalletAccountCategoryID = defaultWalletCategory.ID,
                            WalletAccountCode       = WalletAccount.generateWalletAccountCode(user_entity.ID),
                            Name      = defaultWalletCategory.Name,
                            Balance   = 0,
                            IsDefault = true
                        };

                        _context.WalletAccounts.Add(wallet_account_entity);

                        if (await _context.SaveChangesAsync(cancellationToken) > 0)
                        {
                            user_entity.statusCode = SharedStatusCodes.Created;
                        }
                        else
                        {
                            _context.Users.Remove(user_entity);
                            await _context.SaveChangesAsync(cancellationToken);

                            user_entity.statusCode = SharedStatusCodes.Failed;
                        }
                    }
                    catch (Exception)
                    {
                        _context.Users.Remove(user_entity);
                        await _context.SaveChangesAsync(cancellationToken);

                        user_entity.statusCode = SharedStatusCodes.Failed;
                    }
                }
            }
            catch (Exception)
            {
                user_entity.statusCode = SharedStatusCodes.Failed;
            }

            return(user_entity);
        }
Пример #30
0
        public void TestMakeTransaction1()
        {
            var           snapshot = TestBlockchain.GetTestSnapshot();
            MyWallet      wallet   = new MyWallet();
            Contract      contract = Contract.Create(new ContractParameterType[] { ContractParameterType.Boolean }, new byte[] { 1 });
            WalletAccount account  = wallet.CreateAccount(contract, glkey.PrivateKey);

            account.Lock = false;

            Action action = () => wallet.MakeTransaction(snapshot, new TransferOutput[]
            {
                new TransferOutput()
                {
                    AssetId    = NativeContract.GAS.Hash,
                    ScriptHash = account.ScriptHash,
                    Value      = new BigDecimal(BigInteger.One, 8),
                    Data       = "Dec 12th"
                }
            }, UInt160.Zero);

            action.Should().Throw <InvalidOperationException>();

            action = () => wallet.MakeTransaction(snapshot, new TransferOutput[]
            {
                new TransferOutput()
                {
                    AssetId    = NativeContract.GAS.Hash,
                    ScriptHash = account.ScriptHash,
                    Value      = new BigDecimal(BigInteger.One, 8),
                    Data       = "Dec 12th"
                }
            }, account.ScriptHash);
            action.Should().Throw <InvalidOperationException>();

            action = () => wallet.MakeTransaction(snapshot, new TransferOutput[]
            {
                new TransferOutput()
                {
                    AssetId    = UInt160.Zero,
                    ScriptHash = account.ScriptHash,
                    Value      = new BigDecimal(BigInteger.One, 8),
                    Data       = "Dec 12th"
                }
            }, account.ScriptHash);
            action.Should().Throw <InvalidOperationException>();

            // Fake balance
            var key    = NativeContract.GAS.CreateStorageKey(20, account.ScriptHash);
            var entry1 = snapshot.GetAndChange(key, () => new StorageItem(new AccountState()));

            entry1.GetInteroperable <AccountState>().Balance = 10000 * NativeContract.GAS.Factor;

            key = NativeContract.NEO.CreateStorageKey(20, account.ScriptHash);
            var entry2 = snapshot.GetAndChange(key, () => new StorageItem(new NeoToken.NeoAccountState()));

            entry2.GetInteroperable <NeoToken.NeoAccountState>().Balance = 10000 * NativeContract.NEO.Factor;

            snapshot.Commit();

            var tx = wallet.MakeTransaction(snapshot, new TransferOutput[]
            {
                new TransferOutput()
                {
                    AssetId    = NativeContract.GAS.Hash,
                    ScriptHash = account.ScriptHash,
                    Value      = new BigDecimal(BigInteger.One, 8)
                }
            });

            tx.Should().NotBeNull();

            tx = wallet.MakeTransaction(snapshot, new TransferOutput[]
            {
                new TransferOutput()
                {
                    AssetId    = NativeContract.NEO.Hash,
                    ScriptHash = account.ScriptHash,
                    Value      = new BigDecimal(BigInteger.One, 8),
                    Data       = "Dec 12th"
                }
            });
            tx.Should().NotBeNull();

            entry1 = snapshot.GetAndChange(key, () => new StorageItem(new AccountState()));
            entry2 = snapshot.GetAndChange(key, () => new StorageItem(new AccountState()));
            entry1.GetInteroperable <AccountState>().Balance             = 0;
            entry2.GetInteroperable <NeoToken.NeoAccountState>().Balance = 0;
            snapshot.Commit();
        }