예제 #1
0
        public bool Build(ref BigEndianReader reader, KeyPair keyPairDecryption, bool decrypt = true)
        {
            if (reader.Data.Length < 1)
            {
                return(false);
            }

            byte[] data = reader.Data;
            if (decrypt)
            {
                keyPairDecryption.Decrypt(ref data, 0, reader.Data.Length);
            }

            CompleteData = data;

            reader = new BigEndianReader(data);
            Length = reader.ReadUInt();
            Header = reader.ReadUShort();
            Data   = new byte[reader.BytesAvailable];
            int j = 0;

            for (long i = reader.Position; i < Data.Length; i++)
            {
                Data[j] = reader.Data[i];
                j++;
            }
            //reader.Data.CopyTo(Data, sizeof(uint) + sizeof(ushort) - 1);
            return(true);
        }
예제 #2
0
 /// <summary>
 /// 根据传入的账户信息,对可签名的对象进行签名
 /// </summary>
 /// <param name="verifiable">要签名的数据</param>
 /// <param name="key">用于签名的账户</param>
 /// <returns>返回签名后的结果</returns>
 public static byte[] Sign(this IVerifiable verifiable, KeyPair key)
 {
     using (key.Decrypt())
     {
         return(Crypto.Default.Sign(verifiable.GetHashData(), key.PrivateKey, key.PublicKey.EncodePoint(false).Skip(1).ToArray()));
     }
 }
예제 #3
0
        private void button1_Click(object sender, EventArgs e)
        {
            if (saveFileDialog1.ShowDialog() != DialogResult.OK)
            {
                return;
            }
            KeyPair key = (KeyPair)comboBox1.SelectedItem;

            byte[] pubkey = key.PublicKey.EncodePoint(false).Skip(1).ToArray();
            byte[] prikey;
            using (key.Decrypt())
            {
                const int ECDSA_PRIVATE_P256_MAGIC = 0x32534345;
                prikey = BitConverter.GetBytes(ECDSA_PRIVATE_P256_MAGIC).Concat(BitConverter.GetBytes(32)).Concat(pubkey).Concat(key.PrivateKey).ToArray();
            }
            CX509PrivateKey x509key = new CX509PrivateKey();

            x509key.AlgorithmName = "ECDSA_P256";
            x509key.Import("ECCPRIVATEBLOB", Convert.ToBase64String(prikey));
            Array.Clear(prikey, 0, prikey.Length);
            CX509CertificateRequestPkcs10 request = new CX509CertificateRequestPkcs10();

            request.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextUser, x509key, null);
            request.Subject = new CX500DistinguishedName();
            request.Subject.Encode($"CN={textBox1.Text},C={textBox2.Text},S={textBox3.Text},SERIALNUMBER={textBox4.Text}");
            request.Encode();
            File.WriteAllText(saveFileDialog1.FileName, "-----BEGIN NEW CERTIFICATE REQUEST-----\r\n" + request.RawData + "-----END NEW CERTIFICATE REQUEST-----\r\n");
            Close();
        }
예제 #4
0
 public ViewPrivateKeyDialog(KeyPair key, UInt160 scriptHash)
 {
     InitializeComponent();
     textBox3.Text = Wallet.ToAddress(scriptHash);
     textBox4.Text = key.PublicKey.EncodePoint(true).ToHexString();
     using (key.Decrypt())
     {
         textBox1.Text = key.PrivateKey.ToHexString();
     }
     textBox2.Text = key.Export();
 }
예제 #5
0
        private string Sign(string message, string accountAddr)
        {
            byte[]  data = System.Text.Encoding.UTF8.GetBytes(message);
            KeyPair keys = GetAccountKeyPair(accountAddr);

            using (keys.Decrypt())
            {
                byte[] pubkey = keys.PublicKey.EncodePoint(false).Skip(1).ToArray();
                byte[] result = Crypto.Default.Sign(data, keys.PrivateKey, pubkey);
                return(Convert.ToBase64String(result));
            }
        }
예제 #6
0
        public ViewPrivateKeyDialog(WalletAccount account)
        {
            InitializeComponent();
            KeyPair key = account.GetKey();

            textBox3.Text = account.Address;
            textBox4.Text = key.PublicKey.EncodePoint(true).ToHexString();
            using (key.Decrypt())
            {
                textBox1.Text = key.PrivateKey.ToHexString();
            }
            textBox2.Text = key.Export();
        }
예제 #7
0
        private static void OnReceiveClient(byte[] buffer, int size)
        {
            Debug.Assert(_keyPairClient != null);

            var newBuffer = new byte[buffer.Length];

            buffer.CopyTo(newBuffer, 0);

            _keyPairClient.Decrypt(ref newBuffer, 0, size);

            //Dump(newBuffer, size, "client.txt");

            _client.Send(buffer, size, SocketFlags.None);
        }
예제 #8
0
        public void SetKeyInfo(KeyPair key, UInt160 scriptHash)
        {
            this.Address      = Wallet.ToAddress(scriptHash);
            this.PublicKeyHex = key.PublicKey.EncodePoint(true).ToHexString();
            using (key.Decrypt())
            {
                this.PrivateKeyHex = key.PrivateKey.ToHexString();
            }
            this.PrivateKeyWif = key.Export();

            // Update properties
            NotifyPropertyChanged(nameof(this.Address));
            NotifyPropertyChanged(nameof(this.PublicKeyHex));
            NotifyPropertyChanged(nameof(this.PrivateKeyHex));
            NotifyPropertyChanged(nameof(this.PrivateKeyWif));
        }
예제 #9
0
        private static void OnReceiveServer(byte[] buffer, int size)
        {
            if (_keyPairClient == null && _keyPairServer == null)
            {
                var reader = new BinaryReader(new MemoryStream(buffer, 0, size));
                Debug.Assert(reader.ReadUInt32() == 8);

                var seed = reader.ReadInt32();
                _keyPairClient = new KeyPair(seed);
                _keyPairServer = new KeyPair(seed);
            }
            else
            {
                var newBuffer = new byte[buffer.Length];
                buffer.CopyTo(newBuffer, 0);

                _keyPairServer.Decrypt(ref newBuffer, 0, size);

                //Dump(newBuffer, size, "server.txt");
                DumpInfo(newBuffer);
            }
            _server.Send(buffer, size, SocketFlags.None);
            //_server.BeginSend(buffer, 0, size, SocketFlags.None, ar => _server.EndSend(ar), _server);
        }
예제 #10
0
        protected override void OnDataReceived(byte[] buffer, int offset, int size)
        {
            KeyPair.Decrypt(ref buffer, offset, size);

            if (size < 2)
            {
                OnDisconnected();

                return;
            }

            _lastPacketReceived = DateTime.Now;

            var packets = new List <Packet>();

            var bytesUsed = 0;

            while (bytesUsed < size)
            {
                var packetSize = BitConverter.ToUInt16(buffer, offset + bytesUsed);

                packets.Add(new Packet(buffer, offset + bytesUsed, packetSize));

                bytesUsed += packetSize;
            }

            foreach (var packet in packets)
            {
                if (Constants.LogLevel >= 2)
                {
                    Console.WriteLine("C> {0}", packet.Opcode);
                }

                switch (packet.Opcode)
                {
                case Opcode.CERTIFY:
                    OnCertify(packet);
                    break;

                case Opcode.PING:
                    //Ignore.
                    break;

                case Opcode.QUERYTICKCOUNT:
                    OnQueryTickCount(packet);
                    break;

                case Opcode.COLLECT_CLIENT_LOG:
                    OnCollectClientLog(packet);
                    break;

                case Opcode.LEAVE:
                    Disconnect();             //TODO: Handle this correctly.
                    Database.SaveChanges();
                    Database.DetectChanges();
                    break;

                case Opcode.HOTKEY_CHANGE:
                    OnHotkeyChange(packet);
                    break;

                case Opcode.UPDATE_TASKBAR:
                    OnUpdateTaskbar(packet);
                    break;

                case Opcode.CREATEPLAYER:
                    OnCreatePlayer(packet);
                    break;

                case Opcode.JOIN:
                    OnJoin(packet);
                    break;

                case Opcode.STATE_MSG:
                    OnStateMessage(packet);
                    break;

                case Opcode.MOVEITEM:
                    OnMoveItem(packet);
                    break;

                case Opcode.DROPITEM:
                    OnDropItem(packet);
                    break;

                case Opcode.NORMALCHAT:
                    OnNormalChat(packet);
                    break;

                case Opcode.GMCMD:
                    OnCommand(packet);
                    break;

                case Opcode.GET_CLIENT_INFO:
                    OnGetClientInfo(packet);
                    break;

                default:
                    if (Constants.LogLevel >= 1)
                    {
                        Console.WriteLine("Packet not handled! ({0})", packet.Opcode);
                    }
                    break;
                }
            }

            if (_connected)
            {
                BeginReceive();
            }
        }
        protected override JObject Process(string method, JArray _params)
        {
            switch (method)
            {
            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
                {
                    UInt256            assetId = UInt256.Parse(_params[0].AsString());
                    IEnumerable <Coin> coins   = Program.Wallet.GetCoins().Where(p => !p.State.HasFlag(CoinState.Spent) && p.Output.AssetId.Equals(assetId));
                    JObject            json    = new JObject();
                    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();
                    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 "signdata":
                if (Program.Wallet == null)
                {
                    throw new RpcException(-400, "Access denied");
                }
                else
                {
                    byte[]  data = System.Text.Encoding.UTF8.GetBytes(_params[0].AsString());
                    KeyPair keys = Program.Wallet.GetAccounts().First().GetKey();
                    using (keys.Decrypt())
                    {
                        byte[] pubkey = keys.PublicKey.EncodePoint(false).Skip(1).ToArray();
                        return(Convert.ToBase64String(Crypto.Default.Sign(data, keys.PrivateKey, pubkey)));
                    }
                }

            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);

            case "executescript":
            {
                if (Program.Wallet == null)
                {
                    return(false);
                }
                byte[]            script = _params[0].AsString().HexToBytes();
                ApplicationEngine engine = ApplicationEngine.Run(script);
                Fixed8            gas    = engine.GasConsumed - Fixed8.FromDecimal(10);
                if (gas < Fixed8.Zero)
                {
                    gas = Fixed8.Zero;
                }
                gas = gas.Ceiling();
                Fixed8 fee = gas.Equals(Fixed8.Zero) ? Fixed8.FromDecimal(0.001m) : Fixed8.Zero;
                InvocationTransaction tx = Program.Wallet.MakeTransaction(new InvocationTransaction
                    {
                        Version    = 1,
                        Script     = script,
                        Gas        = gas,
                        Attributes = new TransactionAttribute[0],
                        Inputs     = new CoinReference[0],
                        Outputs    = new TransactionOutput[0]
                    }, fee: fee);
                if (tx == null)
                {
                    return(false);
                }
                ContractParametersContext context;
                try
                {
                    context = new ContractParametersContext(tx);
                }
                catch (Exception)
                {
                    return(false);
                }
                Program.Wallet.Sign(context);
                if (!context.Completed)
                {
                    return(false);
                }
                context.Verifiable.Scripts = context.GetScripts();
                Program.Wallet.ApplyTransaction(tx);
                return(LocalNode.Relay(tx));
            }

            default:
                return(base.Process(method, _params));
            }
        }