Пример #1
0
        /// <summary>
        /// Gets the storage key bytes hash.
        /// </summary>
        /// <param name="module">The module.</param>
        /// <param name="item">The item.</param>
        /// <returns></returns>
        public static byte[] GetStorageKeyBytesHash(string module, string item)
        {
            var mBytes = Encoding.ASCII.GetBytes(module);
            var iBytes = Encoding.ASCII.GetBytes(item);

            return(HashExtension.Twox128(mBytes).Concat(HashExtension.Twox128(iBytes)).ToArray());
        }
Пример #2
0
        /// <summary>
        /// Gets the address from.
        /// </summary>
        /// <param name="bytes">The bytes.</param>
        /// <returns></returns>
        public static string GetAddressFrom(byte[] bytes)
        {
            var SR25519_PUBLIC_SIZE = 32;
            var PUBLIC_KEY_LENGTH   = 32;

            var plainAddr = Enumerable
                            .Repeat((byte)0x2A, 35)
                            .ToArray();

            bytes.CopyTo(plainAddr.AsMemory(1));

            var ssPrefixed  = new byte[SR25519_PUBLIC_SIZE + 8];
            var ssPrefixed1 = new byte[] { 0x53, 0x53, 0x35, 0x38, 0x50, 0x52, 0x45 };

            ssPrefixed1.CopyTo(ssPrefixed, 0);
            plainAddr.AsSpan(0, SR25519_PUBLIC_SIZE + 1).CopyTo(ssPrefixed.AsSpan(7));

            var blake2bHashed = HashExtension.Blake2(ssPrefixed, 0, SR25519_PUBLIC_SIZE + 8);

            plainAddr[1 + PUBLIC_KEY_LENGTH] = blake2bHashed[0];
            plainAddr[2 + PUBLIC_KEY_LENGTH] = blake2bHashed[1];

            var addrCh = Base58.Bitcoin.Encode(plainAddr).ToArray();

            return(new string(addrCh));
        }
Пример #3
0
        /// <summary>
        /// Gets the public key from.
        /// </summary>
        /// <param name="address">The address.</param>
        /// <returns></returns>
        /// <exception cref="ApplicationException">
        /// Address checksum is wrong.
        /// or
        /// Address checksum is wrong.
        /// </exception>
        public static byte[] GetPublicKeyFrom(string address)
        {
            var PUBLIC_KEY_LENGTH = 32;

            var pubkByteList = new List <byte>();

            var bs58decoded = Base58.Bitcoin.Decode(address).ToArray();
            var len         = bs58decoded.Length;

            if (len == 35)
            {
                byte[] ssPrefixed = { 0x53, 0x53, 0x35, 0x38, 0x50, 0x52, 0x45 };
                pubkByteList.AddRange(ssPrefixed);
                pubkByteList.AddRange(bs58decoded.Take(PUBLIC_KEY_LENGTH + 1));

                var blake2bHashed = HashExtension.Blake2(pubkByteList.ToArray(), 512);
                if (bs58decoded[PUBLIC_KEY_LENGTH + 1] != blake2bHashed[0] ||
                    bs58decoded[PUBLIC_KEY_LENGTH + 2] != blake2bHashed[1])
                {
                    throw new ApplicationException("Address checksum is wrong.");
                }

                return(bs58decoded.Skip(1).Take(PUBLIC_KEY_LENGTH).ToArray());
            }

            throw new ApplicationException("Address checksum is wrong.");
        }
        internal static UnCheckedExtrinsic SubmitExtrinsic(bool signed, Account account, Method method, Era era, uint nonce, uint tip, Hash genesis, Hash startEra)
        {
            var uncheckedExtrinsic = new UnCheckedExtrinsic(signed, account, method, era, nonce, tip, genesis, startEra);

            if (!signed)
            {
                return(uncheckedExtrinsic);
            }

            var payload = uncheckedExtrinsic.GetPayload().Encode();

            /// Payloads longer than 256 bytes are going to be `blake2_256`-hashed.
            if (payload.Length > 256)
            {
                payload = HashExtension.Blake2(payload, 256);
            }

            byte[] signature;
            switch (account.KeyType)
            {
            case KeyType.SR25519:
                signature = Sr25519v091.SignSimple(account.PublicKey, account.PrivateKey, payload);
                break;

            case KeyType.ED25519:
                signature = Ed25519.Sign(payload, account.PrivateKey);
                break;

            default:
                throw new Exception($"Unknown key type found '{account.KeyType}'.");
            }

            uncheckedExtrinsic.AddPayloadSignature(signature);
            return(uncheckedExtrinsic);
        }
        public static string GetStorage(Module module, Item item, byte[] parameter = null)
        {
            var mBytes = Encoding.ASCII.GetBytes(module.Name);
            var iBytes = Encoding.ASCII.GetBytes(item.Name);

            var keybytes = HashExtension.XXHash128(mBytes).Concat(HashExtension.XXHash128(iBytes)).ToArray();

            switch (item.Type)
            {
            case Storage.Type.Plain:
                return(BitConverter.ToString(keybytes).Replace("-", ""));

            case Storage.Type.Map:

                switch (item.Function.Hasher)
                {
                case Storage.Hasher.Identity:
                    return(BitConverter.ToString(keybytes.Concat(parameter).ToArray()).Replace("-", ""));

                case Storage.Hasher.Blake2_128:
                case Storage.Hasher.Blake2_256:
                case Storage.Hasher.Blake2_128Concat:
                    return(BitConverter.ToString(keybytes.Concat(HashExtension.Blake2Concat(parameter)).ToArray()).Replace("-", ""));

                case Storage.Hasher.Twox128:
                case Storage.Hasher.Twox256:
                case Storage.Hasher.Twox64Concat:
                case Storage.Hasher.None:
                default:
                    break;
                }
                return("");

            case Storage.Type.DoubleMap:
                return("");

            default:
                return("");
            }
        }
Пример #6
0
        /// <summary>
        /// Create a request for a storage call.
        /// </summary>
        /// <param name="module">The module, is listed in the metadata of the node.</param>
        /// <param name="item">The item, is listed in the metadata of the node.</param>
        /// <param name="parameter">The parameter.</param>
        /// <returns></returns>
        public static string GetStorage(Module module, Item item, string[] key1Param = null, string[] key2Param = null)
        {
            var keybytes = GetStorageKeyBytesHash(module, item);

            byte[] key1ParamBytes = null;
            if (item.Function?.Key1 != null)
            {
                key1ParamBytes = GetParameterBytes(item.Function.Key1, key1Param);
            }

            byte[] key2ParamBytes = null;
            if (item.Function?.Key2 != null)
            {
                key2ParamBytes = GetParameterBytes(item.Function.Key2, key2Param);
            }

            // https://www.shawntabrizi.com/substrate/querying-substrate-storage-via-rpc/
            byte[] key1Hashed, key2Hashed;
            switch (item.Type)
            {
            // xxhash128("ModuleName") + xxhash128("StorageName")
            case Storage.Type.Plain:
                return(Utils.Bytes2HexString(keybytes));

            // xxhash128("ModuleName") + xxhash128("StorageName") + blake256hash("StorageItemKey")
            case Storage.Type.Map:
                key1Hashed = HashExtension.Hash(item.Function.Hasher, key1ParamBytes);
                return(Utils.Bytes2HexString(keybytes.Concat(key1Hashed).ToArray()));

            // xxhash128("ModuleName") + xxhash128("StorageName") + blake256hash("FirstKey") + blake256hash("SecondKey")
            case Storage.Type.DoubleMap:
                key1Hashed = HashExtension.Hash(item.Function.Hasher, key1ParamBytes);
                key2Hashed = HashExtension.Hash(item.Function.Key2Hasher, key2ParamBytes);
                return(Utils.Bytes2HexString(keybytes.Concat(key1Hashed).Concat(key2Hashed).ToArray()));

            default:
                throw new NotSupportedException();
            }
        }