示例#1
0
        private static void TestKey(string[] args)
        {
            var accountId = new AccountId();

            accountId.Create(Utils.GetPublicKeyFrom("5CxW5DWQDpXi4cpACd62wzbPjbYrx4y67TZEmRXBcvmDTNaM"));
            Console.WriteLine($"AccountId: {accountId}");
            Console.WriteLine($"Public Key: {Utils.Bytes2HexString(accountId.Bytes).ToLower()}");

            var str = "0x200101020304050607";

            var memory    = Utils.HexToByteArray(str).AsMemory();
            var vecU8     = new List <U8>();
            var byteArray = memory.ToArray();
            var p         = 0;
            var length    = CompactInteger.Decode(byteArray, ref p);

            Console.WriteLine($"Length: {length}, p = {p}");
            for (var i = 0; i < length; i++)
            {
                var u8 = new U8();
                u8.Decode(byteArray, ref p);
                vecU8.Add(u8);
            }

            Console.WriteLine(JsonConvert.SerializeObject(vecU8));
        }
        public override void Decode(byte[] byteArray, ref int p)
        {
            if (_metaData is null)
            {
                throw new NotImplementedException("Need MetaData in ctor to decode.");
            }

            var start = p;

            var list = new List <EventRecord>();

            var length = CompactInteger.Decode(byteArray, ref p);

            for (var i = 0; i < length; i++)
            {
                var t = new EventRecord(_metaData);
                t.Decode(byteArray, ref p);
                list.Add(t);
            }

            Bytes = byteArray;
            Value = list;

            _size = p - start;
        }
 public void EncodeDecodeTest2()
 {
     for (int i = 0; i < 1000000; i++)
     {
         CompactInteger c = i;
         Assert.AreEqual(c, CompactInteger.Decode(c.Encode()));
     }
 }
 public void EncodeDecodeTest()
 {
     ulong[] array = new UInt64[] { 0, 1, 255, 256, 65535, 4294967295, 4294967296, 8000000000000000000, 18446744073709551615 };
     foreach (var t in array)
     {
         CompactInteger v = new CompactInteger(t);
         Assert.AreEqual(v, CompactInteger.Decode(v.Encode()));
     }
 }
示例#5
0
        public override void Decode(byte[] byteArray, ref int p)
        {
            var start = p;

            var list = new List <T>();

            var length = CompactInteger.Decode(byteArray, ref p);

            for (var i = 0; i < length; i++)
            {
                var t = new T();
                t.Decode(byteArray, ref p);
                list.Add(t);
            }

            _size = p - start;

            var bytes = new byte[_size];

            Array.Copy(byteArray, start, bytes, 0, _size);

            Bytes = bytes;
            Value = list;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="Extrinsic"/> class.
        /// </summary>
        /// <param name="memory">The memory.</param>
        internal Extrinsic(Memory <byte> memory)
        {
            int p = 0;
            int m;

            // length
            var length = CompactInteger.Decode(memory.ToArray(), ref p);

            // signature version
            m = 1;
            var _signatureVersion = memory.Slice(p, m).ToArray()[0];

            Signed             = _signatureVersion >= 0x80;
            TransactionVersion = (byte)(_signatureVersion - (Signed ? 0x80 : 0x00));
            p += m;

            // this part is for signed extrinsics
            if (Signed)
            {
                // start bytes
                m = 1;
                var _startBytes = memory.Slice(p, m).ToArray()[0];
                p += m;

                // sender public key
                m = 32;
                var _senderPublicKey = memory.Slice(p, m).ToArray();
                p += m;

                // sender public key type
                m = 1;
                var _senderPublicKeyType = memory.Slice(p, m).ToArray()[0];
                p += m;

                var account = new Account();
                account.Create((KeyType)_senderPublicKeyType, _senderPublicKey);
                Account = account;

                // signature
                m         = 64;
                Signature = memory.Slice(p, m).ToArray();
                p        += m;

                // era
                m = 1;
                var era = memory.Slice(p, m).ToArray();
                if (era[0] != 0)
                {
                    m   = 2;
                    era = memory.Slice(p, m).ToArray();
                }
                Era = Era.Decode(era);
                p  += m;

                // nonce
                Nonce = CompactInteger.Decode(memory.ToArray(), ref p);

                // tip
                Tip = CompactInteger.Decode(memory.ToArray(), ref p);
            }

            // method
            m = 2;
            var method = memory.Slice(p, m).ToArray();

            p += m;

            // parameters
            var parameter = memory.Slice(p).ToArray();

            Method = new Method(method[0], method[1], parameter);
        }
        private void EvaluateTypedArguments()
        {
            if (Method.Arguments == null || Method.Arguments.Length == 0 || Method.Parameters == null || Method.Parameters.Length == 0)
            {
                Logger.Warn("Can't evaluate typed arguments extrinsic isn't properly enriched.");
            }

            var arguments = Method.Arguments;
            var memory    = Method.Parameters.AsMemory();

            int m;

            for (var i = 0; i < arguments.Length; i++)
            {
                var p        = 0;
                var argument = arguments[i];
                switch (argument.Type)
                {
                case "Compact<T::BlockNumber>":
                    argument.Value = CompactInteger.Decode(memory.ToArray(), ref p);
                    break;

                case "Compact<T::Balance>":
                    argument.Value = CompactInteger.Decode(memory.ToArray(), ref p);
                    break;

                case "Compact<T::Moment>":
                    argument.Value = CompactInteger.Decode(memory.ToArray(), ref p);
                    break;

                case "<T::Lookup as StaticLookup>::Source":
                    m = 1;
                    var _ = memory.Slice(p, m).ToArray()[0];     // public key type
                    p += m;

                    m = 32;
                    argument.Value = Utils.GetAddressFrom(memory.Slice(p, m).ToArray());     // public key
                    p += m;
                    break;

                case "Vec<T::Header>":
                    argument.Value = "Unhandled 'argument.Type'";
                    break;

                case "u8":
                    var u8 = new U8();
                    u8.Decode(memory.Slice(p).ToArray(), ref p);
                    argument.Value = u8.ToString();
                    break;

                case "Option<u8>":
                    var optionU8 = new Option <U8>();
                    optionU8.Decode(memory.Slice(p).ToArray(), ref p);
                    argument.Value = optionU8.OptionFlag ? optionU8.ToString() : "null";
                    break;

                default:
                    Logger.Warn($"Argument is currently unhandled in GetTypedArguments, '{argument.Type}', please add!");
                    argument.Value = $"Unhandled '{argument.Type}'";
                    break;
                }
            }
        }
示例#8
0
        private static void DecodeExtrinsicString()
        {
            const int PUBIC_KEY_SIZE = 32;
            const int SIGNATURE_SIZE = 64;

            // public key                     0x278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e
            // dest public key                                                                                                                                                                                                                              0x9effc1668ca381c242885516ec9fa2b19c67b6684c02a8a3237b6862e5c8cd7e
            //string balanceTransfer = "0x450284278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e004313aef86edd83200a3650bac543a45ce1c3013c29df7ca08a0c6f0e9822057b259b9fa3ef10f950da6b07ddf0b21179a834d92921e1130f9c95018ae3df6c01c502000004009effc1668ca381c242885516ec9fa2b19c67b6684c02a8a3237b6862e5c8cd7e1300008a5d78456301";

            // public key                     0x278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e
            // dest public key                                                                                                                                                                                                                                    0x9effc1668ca381c242885516ec9fa2b19c67b6684c02a8a3237b6862e5c8cd7e
            //string balanceTransfer = "0x3d0284278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e00d517a97eebab11a9d9fa4b8c3961428cd2511e2007a7778da8127bc0f826ca513cc6702675d4d672f823de338c91aea48a573d7f5155d32c583b96fb0b110505c50200c6c96fb904009effc1668ca381c242885516ec9fa2b19c67b6684c02a8a3237b6862e5c8cd7e56346f1d";

            // public key                     0x278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e
            // signature                                                                                        0x14ae74dd7964365038eba44f51c347b9c7070231d56e38ef1024457ebdc6dc03d20226243b1b2731df6fd80f7170643221bd8bf8d06215d4bfeac68a2c9d2305
            // dest public key                                                                                                                                                                                                                                0x9effc1668ca381c242885516ec9fa2b19c67b6684c02a8a3237b6862e5c8cd7e
            //string balanceTransfer = "0x350284278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e0014ae74dd7964365038eba44f51c347b9c7070231d56e38ef1024457ebdc6dc03d20226243b1b2731df6fd80f7170643221bd8bf8d06215d4bfeac68a2c9d2305f50204491304009effc1668ca381c242885516ec9fa2b19c67b6684c02a8a3237b6862e5c8cd7e068d6deb";
            //string balanceTransfer = "0x2d0284d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d01726ba1fab06d3e1bf6abfa0d5af85e25f2a970e11384162b7caf83935c58f769b6fef3b83a29ffd8d813a037d01cd6bcb21beaa88e9a18b3abe366b0458a8a82a5001049130400278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e8543";
            string balanceTransfer  = "0x3102844b94e38b0c2ee21c367d4c9584204ce62edf5b4a6f675f10678cc56b6ea86e71000b893ef2bbed9be566d61d14eba57b454118328929944d71db86b4c7989570be959597948561639da02eadd516f830ff5ba7aab938b87e63bc9d61d1c178e80cb50020000500d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d0284d717";
            string pendingExtrinsic = balanceTransfer;


            //string dmogCreate = "0xa50184278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e00cbbf8076d31e163051556563a9de71816ba05fac08b905b14c2e6d266b7c621f8abadb2776c6d35f1990ed0a3fd768493ce85ac78ef654d69760e7d80273af01f5020849130602";
            //string dmogCreate = "0xa10184d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d01bc9103c06e696c1d110380ddbf8b5b3dc990f1432ea44231e14d0f9f3824f700a067d3695f3050a8eff3d1053c56b1b36550ff93ee79c888a376b9bfa42ebc8f250308000602";
            //string dmogCreate = "0xa10184d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d015aeaba077ee63272f4c32d563ab72301a64e2a4d0bd02445b25cc16e6827e4317ef9304a5af9d5061581b0bf17e8a6a880465ed278251f301bbb3cd719fbf28105030c000602";
            //string dmogCreate = "0xa10184278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e00516811e8fc5c2fe66e86b251fe96a5d3e1bef77a56da8dedac31973018ee27d4a4bd72e34b73f637213e991b35605f236f0136c53627dd620478a4091ae4bd0d001049130602";

            //string dmogCreate   = "0xa10184278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e00743f9c4d923490da02db6567e3128b7af336e3c3ff586dc7c262a787912b251eadd87001192db949215a5a9fb76b7ab2dc50fc70aea3b64a99cd4bc5a423c60a250310000602";
            // public key              0x278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e  824108F78CE80A3772BA19D0EA661D726C32974633058691E73ECCFA6F5E34C89278A756357063FD14942C10E79DB49F712AC5F0D160982C61023D5C19F56E01      0602
            //string dmogCreate = "0xa10184278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e00de0b65d4479f7f041b0af2a519893d9c4dd637ab3baa9e51da894663869304dd5dba12a0e1aa140cf40a07f17f690c0aede100fa083cbdd15c637bc2d044ec04450314000602";


            //string dmogCreate = "0xa10184d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d01448082984004e4dc7cb964eba2eb7201c5686d80e666944e2aa01c2be95eaa5be9d547da63616a82631e87e4078a647fbd07920f97c8ea0993207c0fbdd2a98e150314000602";
            //string dmogCreate = "0xA10184278117FC144C72340F67D0F2316E8386CEFFBF2B2428C9C51FEF7C597F1D426E008C8C7DC53DE26E417D2D1BC0295399D2670361A84D267BD60DE92C2FD7C4C9E515833EEF4107ED71EAC395D4BDAC79C81B144538DFC55090506DC4758D5A3109D50320000602";
            //string pendingExtrinsic = dmogCreate;

            byte[] bytes; // = Utils.HexToByteArray(pendingExtrinsic);

            Console.WriteLine($"author_pendingExtrinsics: {pendingExtrinsic}");
            Console.WriteLine($"********* DECODING *********");
            int p = 0;

            string byteString = pendingExtrinsic.Substring(2);

            // length
            bytes = Utils.HexToByteArray(byteString);
            var length = CompactInteger.Decode(bytes, ref p);

            Console.WriteLine($"length: {length} [{p}]");
            byteString = byteString.Substring(p * 2);

            // signature version [byte]
            byte[] signatureVersion = Utils.HexToByteArray(byteString.Substring(0, 2));
            Console.WriteLine($"signatureVersion: {Utils.Bytes2HexString(signatureVersion)}");
            byteString = byteString.Substring(signatureVersion.Length * 2);
            bytes      = Utils.HexToByteArray(byteString);

            // send public key
            byte[] sendPublicKey = Utils.HexToByteArray(byteString.Substring(0, PUBIC_KEY_SIZE * 2));
            Console.WriteLine($"sendPublicKey: {Utils.GetAddressFrom(sendPublicKey)} [{Utils.Bytes2HexString(sendPublicKey)}]");
            byteString = byteString.Substring(sendPublicKey.Length * 2);
            bytes      = Utils.HexToByteArray(byteString);

            // seperator1
            byte[] sendPublicKeyType = Utils.HexToByteArray(byteString.Substring(0, 2));
            Console.WriteLine($"sendPublicKeyType: {Utils.Bytes2HexString(sendPublicKeyType)}");
            byteString = byteString.Substring(sendPublicKeyType.Length * 2);
            bytes      = Utils.HexToByteArray(byteString);

            // signature
            byte[] signature = Utils.HexToByteArray(byteString.Substring(0, SIGNATURE_SIZE * 2));
            Console.WriteLine($"signature: {Utils.Bytes2HexString(signature)}");
            byteString = byteString.Substring(signature.Length * 2);
            bytes      = Utils.HexToByteArray(byteString);

            // era
            byte[] era = Utils.HexToByteArray(byteString.Substring(0, 4));
            //byte[] era = Utils.HexToByteArray(byteString.Substring(0, 2));
            Console.WriteLine($"era: {Utils.Bytes2HexString(era)}");
            byteString = byteString.Substring(era.Length * 2);
            bytes      = Utils.HexToByteArray(byteString);

            // nonce
            p = 0;
            var nonce = CompactInteger.Decode(bytes, ref p);

            Console.WriteLine($"nonce: {nonce} [{p}]");
            byteString = byteString.Substring(p * 2);
            bytes      = Utils.HexToByteArray(byteString);

            // tip
            p = 0;
            var tip = CompactInteger.Decode(bytes, ref p);

            Console.WriteLine($"tip: {tip} [{p}]");
            byteString = byteString.Substring(p * 2);
            bytes      = Utils.HexToByteArray(byteString);

            // module index
            byte[] moduleIndex = Utils.HexToByteArray(byteString.Substring(0, 4));
            Console.WriteLine($"moduleIndex: {Utils.Bytes2HexString(moduleIndex)}");
            byteString = byteString.Substring(moduleIndex.Length * 2);
            bytes      = Utils.HexToByteArray(byteString);

            byte[] parameters = bytes;

            if (byteString.Length > 0)
            {
                // dest public key
                byte[] destPublicKey = Utils.HexToByteArray(byteString.Substring(0, PUBIC_KEY_SIZE * 2));
                Console.WriteLine($"destPublicKey: {Utils.GetAddressFrom(destPublicKey)} [{Utils.Bytes2HexString(destPublicKey)}]");
                byteString = byteString.Substring(destPublicKey.Length * 2);
                bytes      = Utils.HexToByteArray(byteString);

                // parameters
                p = 0;
                var amount = CompactInteger.Decode(bytes, ref p);
                Console.WriteLine($"amount: {amount} [{p}]");
                byteString = byteString.Substring(p * 2);
                bytes      = Utils.HexToByteArray(byteString);
            }

            Method method = new Method(moduleIndex[0], moduleIndex[1], parameters);

            Era eraObject = new Era(Constants.EXTRINSIC_ERA_PERIOD_DEFAULT, 47, 47 == 0 ? true : false);

            var uncheckedExtrinsic = new UnCheckedExtrinsic(true, new Account(sendPublicKeyType[0] == 0 ? KeyType.ED25519 : KeyType.SR25519, new byte[0], sendPublicKey), method, eraObject, nonce, 1234, new Hash(new byte[0]), new Hash(new byte[0]));

            uncheckedExtrinsic.AddPayloadSignature(signature);

            //Console.WriteLine(Utils.Bytes2HexString(uncheckedExtrinsic.Encode()));
        }
示例#9
0
        private static void ParseExtrinsicVecHeader(string[] args)
        {
            //Console.WriteLine(Utils.Bytes2HexString(Utils.GetPublicKeyFrom("5GX1FSLUkzeUxdRPHrmc3hm8189WT2qQRbWUgy5vhZwgd2XQ")));

            var hexString = "0x" +
                            "0d03" + // length
                            "04" +
                            "040004" +
                            "2ad9b32392b71a2e5fdd210d0be84c152a3bc2571b6223e9100c64bfdd7878b1" + // parentHash
                            "b6d91d00" +                                                         // number
                            "9eee9fd4cf123d08a4fe2f17a1b38ce1a0ded9083c840f3124c567943da29232" + // stateRoot
                            "4054e5b8541167df941d22e69bd16ad3bb8e7307830b7bc8f74954388281f095" + // extrinsicsRoot
                                                                                                 // digest
                            "08064241424534" +
                            "02060000002f6af41f00000000" +
                            "05424142450101" +
                            "2899b12dbf3b94d2fa11bc739a49d485d1528b573497749b72e36a3aaf191e61089289ae084fbbd417435e43d30bcdc3854c3b6fc1965a809f5f34e7682c9c8f";


            //        method:
            //    {
            //    args:
            //        [
            //      [
            //        {
            //        parentHash: 0x2ad9b32392b71a2e5fdd210d0be84c152a3bc2571b6223e9100c64bfdd7878b1,
            //        number: 489,069,
            //        stateRoot: 0x9eee9fd4cf123d08a4fe2f17a1b38ce1a0ded9083c840f3124c567943da29232,
            //        extrinsicsRoot: 0x4054e5b8541167df941d22e69bd16ad3bb8e7307830b7bc8f74954388281f095,
            //        digest:
            //            {
            //            logs:
            //                [
            //              {
            //                PreRuntime:[
            //                 BABE,
            //                 0x02060000002f6af41f00000000
            //                ]
            //            },
            //            {
            //                Seal:[
            //                 BABE,
            //                 0x2899b12dbf3b94d2fa11bc739a49d485d1528b573497749b72e36a3aaf191e61089289ae084fbbd417435e43d30bcdc3854c3b6fc1965a809f5f34e7682c9c8f
            //              ]
            //            }
            //          ]
            //        }
            //        }
            //    ]
            //  ],
            //  method: setUncles,
            //  section: authorship
            //}


            var memory = Utils.HexToByteArray(hexString).AsMemory();

            var p = 0;

            //int m;

            // length
            Console.WriteLine($"length = {CompactInteger.Decode(memory.ToArray(), ref p)}");

            Console.WriteLine($"next? = {CompactInteger.Decode(memory.ToArray(), ref p)}");

            Console.WriteLine($"p = {p}");
        }
示例#10
0
        private static void ParseExtrinsic(string[] args)
        {
            // Reference Substrate 3.0.0
            // Zurich to DotMog, 0.123 DMOG's
            // Nonce 0, Lifetime 64
            // 0x4502
            // 8400
            // 278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e --> 5CxW5DWQDpXi4cpACd62wzbPjbYrx4y67TZEmRXBcvmDTNaM
            // 00a1486b48665121686eddf7029d4f3b2ccf9335824d91df1ff11ffa739756717fe5570f204596fbd27c893981883b25ac797d3935405580d6144b356b469d6709f5020000060000
            // 4d2b23d27e1f6e3733d7ebf3dc04f3d5d0010cd18038055f9bbbab48f460b61e --> 5DotMog6fcsVhMPqniyopz5sEJ5SMhHpz7ymgubr56gDxXwH
            // 0b00b04e2bde6f


            //    {
            //        isSigned: true,
            //        method:
            //        {
            //            args:
            //            [
            //            {
            //                Id: 5DotMog6fcsVhMPqniyopz5sEJ5SMhHpz7ymgubr56gDxXwH
            //            },
            //            1.0000 DMOG
            //                ],
            //            method: transfer,
            //            section: balances
            //        },
            //        era:
            //        {
            //            MortalEra:
            //            {
            //                period: 128,
            //                phase: 50
            //            }
            //        },
            //        nonce: 2,
            //        signature: 0x351b31c6ad373f176a020acf168ca0412a3f410ef6d9936f46f4ce7bc893f76fcf3ff4389de0f86ad6b55df9af0d8ae3b868a544df107698056b7a93202faf00,
            //        signer:
            //        {
            //            Id: 5CxW5DWQDpXi4cpACd62wzbPjbYrx4y67TZEmRXBcvmDTNaM
            //        },
            //        tip: 0
            //    }
            //    ]
            //},
            //0x4902
            //8400
            //278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e
            //00
            //351b31c6ad373f176a020acf168ca0412a3f410ef6d9936f46f4ce7bc893f76fcf3ff4389de0f86ad6b55df9af0d8ae3b868a544df107698056b7a93202faf00 --> signature
            //26030800060000
            //4d2b23d27e1f6e3733d7ebf3dc04f3d5d0010cd18038055f9bbbab48f460b61e
            //0f0080c6a47e8d03

            var accountZurich = Account.Build(
                KeyType.Ed25519,
                Utils.HexToByteArray(
                    "0xf5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e"),
                Utils.GetPublicKeyFrom("5CxW5DWQDpXi4cpACd62wzbPjbYrx4y67TZEmRXBcvmDTNaM"));

            var accountId = new AccountId();

            accountId.Create(Utils.GetPublicKeyFrom("5DotMog6fcsVhMPqniyopz5sEJ5SMhHpz7ymgubr56gDxXwH"));

            var balance = new Balance();

            balance.Create(2000000000000);

            var extrinsic = ExtrinsicCall.BalanceTransfer(accountId, balance);


            Console.WriteLine(CompactInteger.Decode(Utils.HexToByteArray("0x490284")).ToString());
            Console.WriteLine(Utils.Bytes2HexString(new CompactInteger(146).Encode()));

            // 0x4902 Length 146
            // 84
            // 00
            // 278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e --> 5CxW5DWQDpXi4cpACd62wzbPjbYrx4y67TZEmRXBcvmDTNaM
            // 00fb6ec6a0e127329b564367527b3d6c4f28c197d2e205a4d37270e7fe5eee764e1d678e46e2c2d55a1d2cfd7869d24e40ba5f6bd9827c0b95d3db51bc633d050445032400060000
            // 4d2b23d27e1f6e3733d7ebf3dc04f3d5d0010cd18038055f9bbbab48f460b61e --> 5DotMog6fcsVhMPqniyopz5sEJ5SMhHpz7ymgubr56gDxXwH
            // 0f00806d8176de18
        }