Use signed 64 bit integers for better compatibility.
[NovacoinLibrary.git] / Novacoin / CNovacoinAddress.cs
index 5ff3d28..c652b22 100644 (file)
@@ -1,11 +1,31 @@
-\feffusing System;
+\feff/**
+*  Novacoin classes library
+*  Copyright (C) 2015 Alex D. (balthazar.ad@gmail.com)
+
+*  This program is free software: you can redistribute it and/or modify
+*  it under the terms of the GNU Affero General Public License as
+*  published by the Free Software Foundation, either version 3 of the
+*  License, or (at your option) any later version.
+
+*  This program is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU Affero General Public License for more details.
+
+*  You should have received a copy of the GNU Affero General Public License
+*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 using System.Collections.Generic;
 using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System;
+using System.Diagnostics.Contracts;
 
 namespace Novacoin
 {
+    /// <summary>
+    /// Available address types
+    /// </summary>
     public enum AddrType
     {
         PUBKEY_ADDRESS = 8,
@@ -14,74 +34,116 @@ namespace Novacoin
         SCRIPT_ADDRESS_TEST = 196
     };
 
+    /// <summary>
+    /// Represents novacoin address
+    /// </summary>
     public class CNovacoinAddress
     {
         private byte nVersion;
-        private List<byte> addrData;
+        private byte[] addrData = new byte[20];
 
-        public CNovacoinAddress(byte nVersionIn, IEnumerable<byte> addrDataIn)
+        /// <summary>
+        /// Initialize with custom data and version
+        /// </summary>
+        /// <param name="nVersionIn"></param>
+        /// <param name="addrDataIn"></param>
+        public CNovacoinAddress(byte nVersionIn, byte[] addrDataIn)
         {
+            Contract.Requires<ArgumentException>(addrDataIn.Length == 20, "Your data doesn't look like a valid hash160 of some value.");
+
             nVersion = nVersionIn;
-            addrData = addrDataIn.ToList();
+            addrDataIn.CopyTo(addrData, 0);
         }
 
+        /// <summary>
+        /// Initialize new instance of PUBKEY_ADDRESS
+        /// </summary>
+        /// <param name="keyID">CKeyID instance</param>
         public CNovacoinAddress(CKeyID keyID)
         {
             nVersion = (byte)AddrType.PUBKEY_ADDRESS;
-            addrData = new List<byte>(keyID.hashBytes);
+            addrData = keyID;
         }
 
+        /// <summary>
+        /// Initialize new instance of SCRIPT_ADDRESS
+        /// </summary>
+        /// <param name="keyID">CScriptID instance</param>
         public CNovacoinAddress(CScriptID scriptID)
         {
             nVersion = (byte)AddrType.SCRIPT_ADDRESS;
-            addrData = new List<byte>(scriptID.hashBytes);
+            addrData = scriptID;
         }
 
-        public static byte[] ConcatAddress(byte[] RipeHash, byte[] Checksum)
+        /// <summary>
+        /// Initialize new instance from base58 string
+        /// </summary>
+        /// <param name="strNovacoinAddress"></param>
+        public CNovacoinAddress(string strNovacoinAddress)
         {
-            byte[] ret = new byte[RipeHash.Length + 4];
-            Array.Copy(RipeHash, ret, RipeHash.Length);
-            Array.Copy(Checksum, 0, ret, RipeHash.Length, 4);
-            return ret;
+            var RawAddrData = AddressTools.Base58DecodeCheck(strNovacoinAddress);
+
+            if (RawAddrData.Length != 21)
+            {
+                throw new ArgumentException("Though you have provided a correct Base58 representation of some data, this data doesn't represent a valid Novacoin address.");
+            }
+
+            nVersion = RawAddrData[0];
+            Array.Copy(RawAddrData, 1, addrData, 0, 20);
         }
 
-        public bool IsValid()
+        /// <summary>
+        /// 20 bytes, Hash160 of script or public key
+        /// </summary>
+        public static implicit operator byte[](CNovacoinAddress addr)
         {
-            int nExpectedSize = 20;
+            return addr.addrData;
+        }
 
-            switch ((AddrType) nVersion)
+        /// <summary>
+        /// Basic sanity checking
+        /// </summary>
+        public bool IsValid
+        {
+            get
             {
-                case AddrType.PUBKEY_ADDRESS:
-                    nExpectedSize = 20; // Hash of public key
-                    break;
-                case AddrType.SCRIPT_ADDRESS:
-                    nExpectedSize = 20; // Hash of CScript
-                    break;
-                case AddrType.PUBKEY_ADDRESS_TEST:
-                    nExpectedSize = 20;
-                    break;
-                case AddrType.SCRIPT_ADDRESS_TEST:
-                    nExpectedSize = 20;
-                    break;
-                default:
-                    return false;
-            }
+                // Address data is normally generated by RIPEMD-160 hash function
+                int nExpectedSize = 20;
 
-            return addrData.Count == nExpectedSize;
+                switch ((AddrType)nVersion)
+                {
+                    case AddrType.PUBKEY_ADDRESS:
+                        nExpectedSize = 20; // Hash of public key
+                        break;
+                    case AddrType.SCRIPT_ADDRESS:
+                        nExpectedSize = 20; // Hash of CScript
+                        break;
+                    case AddrType.PUBKEY_ADDRESS_TEST:
+                        nExpectedSize = 20;
+                        break;
+                    case AddrType.SCRIPT_ADDRESS_TEST:
+                        nExpectedSize = 20;
+                        break;
+                    default:
+                        return false;
+                }
+
+                return addrData.Length == nExpectedSize;
+            }
         }
 
+        /// <summary>
+        /// Generate base58 serialized representation of novacoin address
+        /// </summary>
+        /// <returns>Base58(data + checksum)</returns>
         public override string ToString()
         {
-            List<byte> r = new List<byte>();
-
-            byte[] checkSum = Hash256.Compute256(addrData).hashBytes;
-            Array.Resize(ref checkSum, 4);
+            var r = new List<byte>();
 
             r.Add(nVersion);
             r.AddRange(addrData);
-            r.AddRange(checkSum);
 
-            return AddressTools.Base58Encode(r.ToArray());
+            return AddressTools.Base58EncodeCheck(r.ToArray());
         }
     }
 }