예제 #1
0
파일: UserWallet.cs 프로젝트: ProDog/Zoro
 private UserWallet(WalletIndexer indexer, string path, byte[] passwordKey, bool create)
 {
     this.indexer = indexer;
     this.path = path;
     if (create)
     {
         this.iv = new byte[16];
         this.masterKey = new byte[32];
         this.accounts = new Dictionary<UInt160, UserWalletAccount>();
         using (RandomNumberGenerator rng = RandomNumberGenerator.Create())
         {
             rng.GetBytes(iv);
             rng.GetBytes(masterKey);
         }
         Version version = Assembly.GetExecutingAssembly().GetName().Version;
         BuildDatabase();
         SaveStoredData("PasswordHash", passwordKey.Sha256());
         SaveStoredData("IV", iv);
         SaveStoredData("MasterKey", masterKey.AesEncrypt(passwordKey, iv));
         SaveStoredData("Version", new[] { version.Major, version.Minor, version.Build, version.Revision }.Select(p => BitConverter.GetBytes(p)).SelectMany(p => p).ToArray());
     }
     else
     {
         byte[] passwordHash = LoadStoredData("PasswordHash");
         if (passwordHash != null && !passwordHash.SequenceEqual(passwordKey.Sha256()))
             throw new CryptographicException();
         this.iv = LoadStoredData("IV");
         this.masterKey = LoadStoredData("MasterKey").AesDecrypt(passwordKey, iv);
         this.accounts = LoadAccounts();
         indexer.RegisterAccounts(accounts.Keys);
     }
     indexer.WalletTransaction += WalletIndexer_WalletTransaction;
 }
예제 #2
0
 public NEP6Wallet(string path, string name = null)
 {
     this.path = path;
     if (File.Exists(path))
     {
         JObject wallet;
         using (StreamReader reader = new StreamReader(path))
         {
             wallet = JObject.Parse(reader);
         }
         this.name     = wallet["name"]?.AsString();
         this.version  = Version.Parse(wallet["version"].AsString());
         this.Scrypt   = ScryptParameters.FromJson(wallet["scrypt"]);
         this.accounts = ((JArray)wallet["accounts"]).Select(p => NEP6Account.FromJson(p, this)).ToDictionary(p => p.ScriptHash);
         this.extra    = wallet["extra"];
         WalletIndexer.RegisterAccounts(accounts.Keys);
     }
     else
     {
         this.name     = name;
         this.version  = Version.Parse("1.0");
         this.Scrypt   = ScryptParameters.Default;
         this.accounts = new Dictionary <UInt160, NEP6Account>();
         this.extra    = JObject.Null;
     }
     WalletIndexer.BalanceChanged += WalletIndexer_BalanceChanged;
 }
예제 #3
0
 private void AddAccount(NEP6Account account, bool is_import)
 {
     lock (accounts)
     {
         if (accounts.TryGetValue(account.ScriptHash, out NEP6Account account_old))
         {
             account.Label     = account_old.Label;
             account.IsDefault = account_old.IsDefault;
             account.Lock      = account_old.Lock;
             if (account.Contract == null)
             {
                 account.Contract = account_old.Contract;
             }
             else
             {
                 NEP6Contract contract_old = (NEP6Contract)account_old.Contract;
                 if (contract_old != null)
                 {
                     NEP6Contract contract = (NEP6Contract)account.Contract;
                     contract.ParameterNames = contract_old.ParameterNames;
                     contract.Deployed       = contract_old.Deployed;
                 }
             }
             account.Extra = account_old.Extra;
         }
         else
         {
             WalletIndexer.RegisterAccounts(new[] { account.ScriptHash }, is_import ? 0 : Blockchain.Default?.Height ?? 0);
         }
         accounts[account.ScriptHash] = account;
     }
 }
예제 #4
0
        /// <summary>
        /// 使用钱包文件初始化钱包
        ///
        /// Add Code
        /// </summary>
        /// <param name="path">钱包文件路径</param>
        /// <param name="password">密码</param>
        /// <param name="type">账号类型</param>
        public NEP6Wallet(string path, string password, int type = 0)
        {
            this.type = type;
            this.path = path;
            // 钱包文件是否存在
            if (!File.Exists(path))
            {
                throw new FileNotFoundException();
            }
            // 打开钱包
            JObject wallet;

            using (StreamReader reader = new StreamReader(path))
            {
                wallet = JObject.Parse(reader);
            }
            //Console.WriteLine($"Wallet Name: {wallet["version"].AsString()}");
            this.name    = wallet["name"]?.AsString();
            this.version = Version.Parse(wallet["version"].AsString());
            this.Scrypt  = ScryptParameters.FromJson(wallet["scrypt"]);
            // 把文件中的账号信息转换成 NEP6Account 并加入到 accounts  键名是  ScriptHash
            this.accounts = ((JArray)wallet["accounts"]).Select(p => NEP6Account.fromJson(p, this)).ToDictionary(p => p.ScriptHash);
            //foreach (UInt160 key in this.accounts.Keys)
            //{
            //    this.accounts[key].GetKey();
            //}
            this.extra = wallet["extra"];
            WalletIndexer.RegisterAccounts(accounts.Keys);
        }
예제 #5
0
 /// <summary>
 /// 使用wifkey或nep2key初始化钱包
 /// AddCode
 /// </summary>
 /// <param name="wifKey"></param>
 /// <param name="nep2key"></param>
 /// <param name="password"></param>
 /// <param name="name"></param>
 public NEP6Wallet(string wifKey, string nep2key, string password, string name = null)
 {
     this.type     = 0;
     this.name     = name;
     this.version  = Version.Parse("1.0");
     this.accounts = new Dictionary <UInt160, NEP6Account>();
     this.Scrypt   = ScryptParameters.Default;
     this.extra    = JObject.Null;
     // 以Wif私钥的方式打开钱包 add code
     if (!string.IsNullOrEmpty(wifKey))
     {
         var account = Import(wifKey, password);
         account.GetKey();
         account.Print();
         WalletIndexer.RegisterAccounts(accounts.Keys);
         WalletIndexer.BalanceChanged += WalletIndexer_BalanceChanged;
     }
     else if (!string.IsNullOrEmpty(nep2key))
     {
         this.password = password;
         //Console.WriteLine($"password: {password}");
         var account = Import(nep2key, password);
         account.GetKey();
         account.Print();
         WalletIndexer.RegisterAccounts(accounts.Keys);
         WalletIndexer.BalanceChanged += WalletIndexer_BalanceChanged;
     }
 }
예제 #6
0
        /// <summary>
        /// 使用公钥初始化钱包
        /// Add Code
        /// </summary>
        /// <param name="publicKey"></param>
        /// <param name="address"></param>
        /// <param name="name"></param>
        public NEP6Wallet(string publicKey, string address, string name)
        {
            this.type     = 0;
            this.name     = name;
            this.version  = Version.Parse("1.0");
            this.accounts = new Dictionary <UInt160, NEP6Account>();
            this.Scrypt   = ScryptParameters.Default;
            this.extra    = JObject.Null;
            var accout = ImportFromPublicKey(publicKey);

            //account.GetKey();
            WalletIndexer.RegisterAccounts(accounts.Keys);
            WalletIndexer.BalanceChanged += WalletIndexer_BalanceChanged;
        }
예제 #7
0
        /// <summary>
        /// 注册本地钱包
        /// Add Code
        /// </summary>
        /// <param name="publicKey">公钥</param>
        public void RegisterLocalWallet(string publicKey)
        {
            KeyPair      key      = new KeyPair(publicKey);
            NEP6Contract contract = new NEP6Contract
            {
                Script         = Contract.CreateSignatureRedeemScript(key.PublicKey),
                ParameterList  = new[] { ContractParameterType.Signature },
                ParameterNames = new[] { "signature" },
                Deployed       = false
            };
            Dictionary <UInt160, UInt160> keys = new Dictionary <UInt160, UInt160>();

            keys.Add(contract.ScriptHash, contract.ScriptHash);
            Console.WriteLine($"ScriptHash: {contract.ScriptHash.ToString()}");
            WalletIndexer.RegisterAccounts(keys.Keys);
        }
예제 #8
0
        private UserWallet(string path, byte[] passwordKey)
        {
            this.path = path;
            byte[] passwordHash = LoadStoredData("PasswordHash");
            if (passwordHash != null && !passwordHash.SequenceEqual(passwordKey.Sha256()))
            {
                throw new CryptographicException();
            }
            this.iv        = LoadStoredData("IV");
            this.masterKey = LoadStoredData("MasterKey").AesDecrypt(passwordKey, iv);
#if NET47
            ProtectedMemory.Protect(masterKey, MemoryProtectionScope.SameProcess);
#endif
            this.accounts = LoadAccounts();
            WalletIndexer.RegisterAccounts(accounts.Keys);
            WalletIndexer.BalanceChanged += WalletIndexer_BalanceChanged;
        }
예제 #9
0
        public NEP6Wallet(WalletIndexer indexer, string path, string name = null)
        {
            this.indexer = indexer;
            this.path    = path;
            if (File.Exists(path))
            {
                JObject wallet;
                using (StreamReader reader = new StreamReader(path))
                {
                    wallet = JObject.Parse(reader);
                }
                this.name     = wallet["name"]?.AsString();
                this.version  = Version.Parse(wallet["version"].AsString());
                this.Scrypt   = ScryptParameters.FromJson(wallet["scrypt"]);
                this.accounts = ((JArray)wallet["accounts"]).Select(p => NEP6Account.FromJson(p, this)).ToDictionary(p => p.ScriptHash);
                var jar = wallet["partners"];
                if (jar != default)
                {
                    this.Partners = ((JArray)jar).Select(p => NEP6Partner.FromJson(p)).ToDictionary(p => p.Address);
                }
                var sts = wallet["stones"];
                if (sts != default)
                {
                    this.Stones = ((JArray)sts).Select(p => NEP6Stone.FromJson(p)).ToDictionary(p => $"{p.Type}#{p.Key}");
                }
                this.extra = wallet["extra"];

                indexer?.RegisterAccounts(accounts.Keys);
            }
            else
            {
                this.name     = name;
                this.version  = Version.Parse("1.0");
                this.Scrypt   = ScryptParameters.Default;
                this.accounts = new Dictionary <UInt160, NEP6Account>();
                this.Partners = new Dictionary <string, NEP6Partner>();
                this.Stones   = new Dictionary <string, NEP6Stone>();
                this.extra    = JObject.Null;
            }

            if (indexer != null)
            {
                indexer.WalletTransaction += WalletIndexer_WalletTransaction;
            }
        }
예제 #10
0
        private UserWallet(string path, byte[] passwordKey, bool create)
        {
            TR.Enter();
            this.path = path;
            if (create)
            {
                this.iv        = new byte[16];
                this.masterKey = new byte[32];
                this.accounts  = new Dictionary <UInt160, UserWalletAccount>();
                using (RandomNumberGenerator rng = RandomNumberGenerator.Create())
                {
                    rng.GetBytes(iv);
                    rng.GetBytes(masterKey);
                }
                Version version = Assembly.GetExecutingAssembly().GetName().Version;
                BuildDatabase();
                SaveStoredData("PasswordHash", passwordKey.Sha256());
                SaveStoredData("IV", iv);
                SaveStoredData("MasterKey", masterKey.AesEncrypt(passwordKey, iv));
                SaveStoredData("Version", new[] { version.Major, version.Minor, version.Build, version.Revision }.Select(p => BitConverter.GetBytes(p)).SelectMany(p => p).ToArray());
#if NET47
                ProtectedMemory.Protect(masterKey, MemoryProtectionScope.SameProcess);
#endif
            }
            else
            {
                byte[] passwordHash = LoadStoredData("PasswordHash");
                if (passwordHash != null && !passwordHash.SequenceEqual(passwordKey.Sha256()))
                {
                    TR.Exit();
                    throw new CryptographicException();
                }
                this.iv        = LoadStoredData("IV");
                this.masterKey = LoadStoredData("MasterKey").AesDecrypt(passwordKey, iv);
#if NET47
                ProtectedMemory.Protect(masterKey, MemoryProtectionScope.SameProcess);
#endif
                this.accounts = LoadAccounts();
                WalletIndexer.RegisterAccounts(accounts.Keys);
            }
            WalletIndexer.BalanceChanged += WalletIndexer_BalanceChanged;
            TR.Exit();
        }
예제 #11
0
 public NEP6Wallet(string path, string name = null)
 {
     this.type = 0;
     // 以文件的形式打开钱包
     this.path = path;
     //Console.WriteLine($"NEP6Wallet Path: {this.path}");
     if (File.Exists(path)) // 通过文件加载钱包
     {
         //Console.WriteLine($"NEP6Wallet Path: {this.path}");
         JObject wallet;
         using (StreamReader reader = new StreamReader(path))
         {
             wallet = JObject.Parse(reader);
         }
         //Console.WriteLine($"Wallet Name: {wallet["version"].AsString()}");
         this.name    = wallet["name"]?.AsString();
         this.version = Version.Parse(wallet["version"].AsString());
         this.Scrypt  = ScryptParameters.FromJson(wallet["scrypt"]);
         // 把文件中的账号信息转换成 NEP6Account 并加入到 accounts  键名是  ScriptHash
         this.accounts = ((JArray)wallet["accounts"]).Select(p => NEP6Account.FromJson(p, this)).ToDictionary(p => p.ScriptHash);
         //foreach (UInt160 key in this.accounts.Keys)
         //{
         //    this.accounts[key].GetKey();
         //}
         this.extra = wallet["extra"];
         WalletIndexer.RegisterAccounts(accounts.Keys);
     }
     else
     {
         this.name     = name;
         this.version  = Version.Parse("1.0");
         this.Scrypt   = ScryptParameters.Default;
         this.accounts = new Dictionary <UInt160, NEP6Account>();
         this.extra    = JObject.Null;
     }
     WalletIndexer.BalanceChanged += WalletIndexer_BalanceChanged;
 }
예제 #12
0
 private void AddAccount(NEP6Account account, bool is_import)
 {
     lock (accounts)
     {
         //bool ok = false;
         if (accounts.TryGetValue(account.ScriptHash, out NEP6Account account_old))
         {
             account.Label     = account_old.Label;
             account.IsDefault = account_old.IsDefault;
             account.Lock      = account_old.Lock;
             if (account.Contract == null)
             {
                 account.Contract = account_old.Contract;
             }
             else
             {
                 NEP6Contract contract_old = (NEP6Contract)account_old.Contract;
                 if (contract_old != null)
                 {
                     NEP6Contract contract = (NEP6Contract)account.Contract;
                     contract.ParameterNames = contract_old.ParameterNames;
                     contract.Deployed       = contract_old.Deployed;
                 }
             }
             account.Extra = account_old.Extra;
         }
         else
         {
             indexer?.RegisterAccounts(new[] { account.ScriptHash }, is_import ? 0 : Blockchain.Singleton.Height);
             //ok = true;
         }
         accounts[account.ScriptHash] = account;
         //if (ok)
         //    this.ChangeAccount(WalletAccountChangeEventType.Register, account.ScriptHash);
     }
 }
예제 #13
0
 private void AddAccount(UserWalletAccount account, bool is_import)
 {
     lock (accounts)
     {
         if (accounts.TryGetValue(account.ScriptHash, out UserWalletAccount account_old))
         {
             if (account.Contract == null)
             {
                 account.Contract = account_old.Contract;
             }
         }
         else
         {
             WalletIndexer.RegisterAccounts(new[] { account.ScriptHash }, is_import ? 0 : Blockchain.Default?.Height ?? 0);
         }
         accounts[account.ScriptHash] = account;
     }
     using (WalletDataContext ctx = new WalletDataContext(path))
     {
         if (account.HasKey)
         {
             byte[] decryptedPrivateKey = new byte[96];
             Buffer.BlockCopy(account.Key.PublicKey.EncodePoint(false), 1, decryptedPrivateKey, 0, 64);
             using (account.Key.Decrypt())
             {
                 Buffer.BlockCopy(account.Key.PrivateKey, 0, decryptedPrivateKey, 64, 32);
             }
             byte[] encryptedPrivateKey = EncryptPrivateKey(decryptedPrivateKey);
             Array.Clear(decryptedPrivateKey, 0, decryptedPrivateKey.Length);
             Account db_account = ctx.Accounts.FirstOrDefault(p => p.PublicKeyHash.SequenceEqual(account.Key.PublicKeyHash.ToArray()));
             if (db_account == null)
             {
                 db_account = ctx.Accounts.Add(new Account
                 {
                     PrivateKeyEncrypted = encryptedPrivateKey,
                     PublicKeyHash       = account.Key.PublicKeyHash.ToArray()
                 }).Entity;
             }
             else
             {
                 db_account.PrivateKeyEncrypted = encryptedPrivateKey;
             }
         }
         if (account.Contract != null)
         {
             Contract db_contract = ctx.Contracts.FirstOrDefault(p => p.ScriptHash.SequenceEqual(account.Contract.ScriptHash.ToArray()));
             if (db_contract != null)
             {
                 db_contract.PublicKeyHash = account.Key.PublicKeyHash.ToArray();
             }
             else
             {
                 ctx.Contracts.Add(new Contract
                 {
                     RawData       = ((VerificationContract)account.Contract).ToArray(),
                     ScriptHash    = account.Contract.ScriptHash.ToArray(),
                     PublicKeyHash = account.Key.PublicKeyHash.ToArray()
                 });
             }
         }
         //add address
         {
             Address db_address = ctx.Addresses.FirstOrDefault(p => p.ScriptHash.SequenceEqual(account.Contract.ScriptHash.ToArray()));
             if (db_address == null)
             {
                 ctx.Addresses.Add(new Address
                 {
                     ScriptHash = account.Contract.ScriptHash.ToArray()
                 });
             }
         }
         ctx.SaveChanges();
     }
 }