예제 #1
0
        public void Blake2s_Hash()
        {
            var hasher = new Blake2s();
            var result = hasher.Digest(testValue2).ToHexString();

            Assert.Equal("c3ee938582d70ccd9a323b6097357449365d1fdfbbe2ecd7ee44e4bdbbb24392", result);
        }
예제 #2
0
        public void TestSplits()
        {
            var data = Enumerable.Range(0, 256).Select(i => (byte)i).ToArray().AsSpan();

            using (var hasher = new Blake2s())
            {
                var hash1 = new byte[hasher.HashLen];
                var hash2 = new byte[hasher.HashLen];

                for (int i = 0; i <= data.Length; ++i)
                {
                    hasher.AppendData(data.Slice(0, i));
                    hasher.GetHashAndReset(hash1);

                    for (int j = 0; j <= i; ++j)
                    {
                        for (int k = j; k <= i; ++k)
                        {
                            hasher.AppendData(data.Slice(0, j));
                            hasher.AppendData(data.Slice(j, k - j));
                            hasher.AppendData(data.Slice(k, i - k));
                            hasher.GetHashAndReset(hash2);

                            Assert.Equal(hash1, hash2);
                        }
                    }
                }
            }
        }
예제 #3
0
        public void TestVectors()
        {
            var s    = File.ReadAllText("Vectors/blake2-kat.json");
            var json = JArray.Parse(s);

            using (var hasher = new Blake2s())
            {
                byte[] hash = new byte[hasher.HashLen];

                foreach (var vector in json)
                {
                    var name   = (string)vector["hash"];
                    var input  = Hex.Decode((string)vector["in"]);
                    var key    = (string)vector["key"];
                    var output = Hex.Decode((string)vector["out"]);

                    if (name == "blake2s" && String.IsNullOrEmpty(key))
                    {
                        hasher.AppendData(input);
                        hasher.GetHashAndReset(hash);

                        Assert.Equal(output, hash);
                    }
                }
            }
        }
예제 #4
0
        public override Task AddTraceAsync(TraceEntity traceEntity)
        {
            // Allocate dictionary for mapping instruction addresses to memory access hashes
            Dictionary <ulong, byte[]> instructionHashes = new Dictionary <ulong, byte[]>();

            // Hash all memory access instructions
            foreach (var traceEntry in traceEntity.PreprocessedTraceFile.Entries)
            {
                // Extract instruction and memory address
                ulong instructionAddress;
                ulong memoryAddress;
                switch (traceEntry.EntryType)
                {
                case TraceEntry.TraceEntryTypes.HeapMemoryAccess:
                {
                    var heapMemoryAccess = (TraceEntryTypes.HeapMemoryAccess)traceEntry;
                    instructionAddress = ((ulong)heapMemoryAccess.InstructionImageId << 32) | heapMemoryAccess.InstructionRelativeAddress;
                    memoryAddress      = ((ulong)heapMemoryAccess.MemoryAllocationBlockId << 32) | heapMemoryAccess.MemoryRelativeAddress;
                    break;
                }

                case TraceEntry.TraceEntryTypes.ImageMemoryAccess:
                {
                    var imageMemoryAccess = (TraceEntryTypes.ImageMemoryAccess)traceEntry;
                    instructionAddress = ((ulong)imageMemoryAccess.InstructionImageId << 32) | imageMemoryAccess.InstructionRelativeAddress;
                    memoryAddress      = ((ulong)imageMemoryAccess.MemoryImageId << 32) | imageMemoryAccess.MemoryRelativeAddress;
                    break;
                }

                case TraceEntry.TraceEntryTypes.StackMemoryAccess:
                {
                    var stackMemoryAccess = (TraceEntryTypes.StackMemoryAccess)traceEntry;
                    instructionAddress = ((ulong)stackMemoryAccess.InstructionImageId << 32) | stackMemoryAccess.InstructionRelativeAddress;
                    memoryAddress      = stackMemoryAccess.MemoryRelativeAddress;
                    break;
                }

                default:
                    continue;
                }

                // Update hash
                byte[] hash;
                if (!instructionHashes.TryGetValue(instructionAddress, out hash))
                {
                    hash = new byte[32];
                    instructionHashes.Add(instructionAddress, hash);
                }
                var hashSpan = hash.AsSpan();
                MemoryMarshal.Write(hashSpan, ref memoryAddress); // Will overwrite first 8 bytes of hash
                Blake2s.ComputeAndWriteHash(hashSpan, hashSpan);
            }

            // Store instruction hashes
            _testcaseInstructionHashes.AddOrUpdate(traceEntity.Id, instructionHashes, (t, h) => h);

            // Done
            return(Task.CompletedTask);
        }
예제 #5
0
    public void Blake2s_Hash_Empty()
    {
        var hasher = new Blake2s();
        var hash   = new byte[32];

        hasher.Digest(Array.Empty <byte>(), hash);
        var result = hash.ToHexString();

        Assert.Equal("69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9", result);
    }
예제 #6
0
    private static byte[] blake2sSelfTest()
    {
        var inc = Blake2s.CreateIncrementalHasher(blake2sCheck.Length);

        foreach (int diglen in new[] { 16, 20, 28, 32 })
        {
            foreach (int msglen in new[] { 0, 3, 64, 65, 255, 1024 })
            {
                var msg = getTestSequence(msglen);
                var key = getTestSequence(diglen);

                inc.Update(Blake2s.ComputeHash(diglen, msg));
                inc.Update(Blake2s.ComputeHash(diglen, key, msg));
            }
        }

        return(inc.Finish());
    }
예제 #7
0
    private static byte[] blake2sNoAllocSelfTest()
    {
        Span <byte> buff = stackalloc byte[Blake2b.DefaultDigestLength];
        var         inc  = Blake2s.CreateIncrementalHasher(blake2sCheck.Length);

        foreach (int diglen in new[] { 16, 20, 28, 32 })
        {
            foreach (int msglen in new[] { 0, 3, 64, 65, 255, 1024 })
            {
                var msg = getTestSequence(msglen);
                var key = getTestSequence(diglen);

                Blake2s.ComputeAndWriteHash(diglen, msg, buff);
                inc.Update(buff.Slice(0, diglen));

                Blake2s.ComputeAndWriteHash(diglen, key, msg, buff);
                inc.Update(buff.Slice(0, diglen));
            }
        }

        return(inc.TryFinish(buff, out int len) ? buff.Slice(0, len).ToArray() : Array.Empty <byte>());
    }
예제 #8
0
    private static byte[] blake2sHmacSelfTest()
    {
        using var inc = Blake2s.CreateHashAlgorithm(blake2bCheck.Length);

        foreach (int diglen in new[] { 16, 20, 28, 32 })
        {
            using var halg = Blake2s.CreateHashAlgorithm(diglen);
            using var hmac = Blake2s.CreateHMAC(diglen, getTestSequence(diglen));

            foreach (int msglen in new[] { 0, 3, 64, 65, 255, 1024 })
            {
                var msg = getTestSequence(msglen);

                inc.TransformBlock(halg.ComputeHash(msg), 0, diglen, null, 0);
                inc.TransformBlock(hmac.ComputeHash(msg), 0, diglen, null, 0);
            }
        }

        inc.TransformFinalBlock(Array.Empty <byte>(), 0, 0);
        var hash = inc.Hash;

        return(hash);
    }
예제 #9
0
        public void TestLargeInput()
        {
            var factor = 1031;
            var data   = new byte[factor];

            using (var hasher = new Blake2s())
            {
                int count = 4 * factor * factor;

                for (int i = 0; i < count; ++i)
                {
                    hasher.AppendData(data);
                }

                var hash = new byte[hasher.HashLen];
                hasher.GetHashAndReset(hash);

                string expected = "3c965aaac533c5a1715a40ae8beaf8d1fe1242502f2c30db34239b16c54b1d78";
                string actual   = Hex.Encode(hash);

                Assert.Equal(expected, actual);
            }
        }
예제 #10
0
        public void Blake2s_Hash_Should_Throw_On_Null_Input()
        {
            var hasher = new Blake2s();

            Assert.Throws <ArgumentNullException>(() => hasher.Digest(null));
        }
        public void Crypto1Test()
        {
            var sourceStr   = "FeFjpcsfHErXPk5HkfVcwH6zYaRT2xNytDTeSjfuVywt";
            var sourceByte  = SimpleBase.Base58.Bitcoin.Decode(sourceStr).ToArray();
            var privateByte = SimpleBase.Base58.Bitcoin.Decode("ohPH5zghdzmRDxd978r7y6r8YFoTcKm1MgW2gzik3omCuZLysjwNjTd9hnGREFyQHqhShoU4ri7q748UgdwZpzA").ToArray();


            using (var _api = BCTransactionTools.CreateContextBC("165.22.220.8", 9090, 60000))
            {
                //   WalletDataGetResult WalletData = _api._connect.WalletDataGet(sourceByte);
                //   long transactionId = WalletData.WalletData.LastTransactionId + 1;
                var transactionId = _api.WalletDataGet(sourceByte).WalletData.LastTransactionId + 1;
                //     var connect = _api._connect;
                //   for (int i = 0; i <= 19; i++)
                {
                    transactionId++;
                    Transaction transac = new Transaction
                    {
                        Id     = transactionId,
                        Source = sourceByte,
                        Amount = BCTransactionTools.GetAmountByDouble_C(0.1M),
                        Fee    = BCTransactionTools.EncodeFeeFromDouble(0.1),

                        // если перевод смарта то таргет публичник смарта
                        Target = SimpleBase.Base58.Bitcoin.Decode("FY8J5uSb2D3qX3iwUSvcUSGvrBGAvsrXxKxMQdFfpdmm").ToArray(),
                        // если перевод CS - то адресат назначения.
                        //"DM79n9Lbvm3XhBf1LwyBHESaRmJEJez2YiL549ArcHDC"),
                        // UserFields = model.UserData
                    };
                    transac.UserFields = new byte[5];
                    #region ДЕПЛОЙ СМАРТА (убрать if при необходимости)
                    if (1 == 2)
                    {
                        string codeSmart  = "";
                        Byte[] byteSource = transac.Source;
                        //code
                        var byteCodes =
                            _api.SmartContractCompile(codeSmart);
                        if (byteCodes.Status.Code > 0)
                        {
                            throw new Exception(byteCodes.Status.Message);
                        }
                        foreach (var item in byteCodes.ByteCodeObjects)
                        {
                            byteSource.Concat(item.ByteCode);
                        }
                        transac.Target        = Blake2s.ComputeHash(byteSource);
                        transac.SmartContract = new SmartContractInvocation()
                        {
                            SmartContractDeploy = new SmartContractDeploy()
                            {
                                SourceCode      = codeSmart,
                                ByteCodeObjects = byteCodes.ByteCodeObjects
                            }
                        };
                    }

                    #endregion


                    #region ВЫЗОВ МЕТОДА СМАРТА (убрать if при необходимости)

                    if (1 == 2)
                    {
                        transac.SmartContract = new SmartContractInvocation()
                        {
                            Method = "transfer",
                            Params = new List <Variant>()
                            {
                                new Variant()
                                {
                                    // адресат перевода
                                    V_string = "DM79n9Lbvm3XhBf1LwyBHESaRmJEJez2YiL549ArcHDC"
                                               //      { Value = "DM79n9Lbvm3XhBf1LwyBHESaRmJEJez2YiL549ArcHDC", Key = "STRING" },
                                               //           new Credtis_Api_Connect.Model.ParamsCreateModel { Value = "0.5", Key = "STRING" }
                                },
                                new Variant()
                                {
                                    V_string = "0.5"
                                }
                            }
                        };
                    }

                    #endregion



                    transac.Currency = 1;
                    Console.WriteLine(SimpleBase.Base58.Bitcoin.Encode(BCTransactionTools.CreateByteHashByTransaction(transac)));

                    Rebex.Security.Cryptography.Ed25519 crypt = new Rebex.Security.Cryptography.Ed25519();
                    crypt.FromPrivateKey(privateByte);
                    // var b58 = new SimpleBase.Base58();


                    transac.Signature = crypt
                                        .SignMessage(BCTransactionTools.CreateByteHashByTransaction(transac));

                    Console.WriteLine();
                    Console.WriteLine(SimpleBase.Base58.Bitcoin.Encode(transac.Signature));
                    //  Console.WriteLine(BitConverter.ToString(transac.Signature)); // работает в старом вариант


                    //  var  _api1 = BCTransactionTools.CreateContextBC("165.22.220.8", 9090, 6000);
                    //   var res = _api.TransactionFlow(transac);
                    Console.WriteLine();
                    //  Console.WriteLine(BitConverter.ToString(BCTransactionTools.CreateByteHashByTransaction(transac)).Replace("-",""));
                    //      = Res1;
                }
            }
        }
예제 #12
0
        public static void WireguardTest()
        {
            var protocol = new Protocol(
                HandshakePattern.IK,
                CipherFunction.ChaChaPoly,
                HashFunction.Blake2s,
                PatternModifiers.Psk2
                );
            var buffer     = new byte[Protocol.MaxMessageLength];
            var buffer2    = new byte[Protocol.MaxMessageLength];
            int bufferRead = 0;

            using (var hs = protocol.Create(true,
                                            new ReadOnlySpan <byte>(Encoding.UTF8.GetBytes("WireGuard v1 zx2c4 [email protected]")),
                                            OurPrivate,
                                            TheirPublic,
                                            new byte[][] { Preshared }))
            {
                var now    = DateTimeOffset.UtcNow; //replace with Noda.Time?
                var tai64n = new byte[12];
                (4611686018427387914ul + (ulong)now.ToUnixTimeSeconds()).ToBigEndian(tai64n);
                ((uint)(now.Millisecond * 1e6)).ToBigEndian(tai64n, 8);

                var initiationPacket = new List <byte> {
                    1, 0, 0, 0
                };                                                              //type initiation
                initiationPacket.AddRange(((uint)28).ToLittleEndian());         //sender, random 4byte

                var(bytesWritten, _, _) = hs.WriteMessage(tai64n, buffer);
                initiationPacket.AddRange(buffer.Take(bytesWritten));           // should be 24byte, ephemeral, static, timestamp

                var hasher   = Blake2s.CreateIncrementalHasher(32);
                var hashThis = Encoding.UTF8.GetBytes("mac1----").Concat(TheirPublic).ToArray();
                hasher.Update(hashThis);
                var finishedHash = hasher.Finish();
                hasher   = Blake2s.CreateIncrementalHasher(16, finishedHash);
                hashThis = initiationPacket.ToArray();
                hasher.Update(hashThis);

                finishedHash = hasher.Finish();
                initiationPacket.AddRange(finishedHash);                        //mac1
                initiationPacket.AddRange(Enumerable.Repeat((byte)0, 16));      //mac2 = zeros if no cookie last received


                var socket         = new DatagramSocket();
                var responsePacket = new TaskCompletionSource <int>();
                var autoResetEvent = new AutoResetEvent(false);
                socket.MessageReceived += (sender, args) =>
                {
                    bufferRead = args.GetDataStream().AsStreamForRead().Read(buffer);
                    autoResetEvent.Set();
                };
                socket.ConnectAsync(new HostName("demo.wireguard.com"), "12913").AsTask().Wait();
                var streamWriter = new BinaryWriter(socket.OutputStream.AsStreamForWrite());
                streamWriter.Write(initiationPacket.ToArray());
                streamWriter.Flush();

                var successful = autoResetEvent.WaitOne(5000);
                if (!successful)
                {
                    return;
                }

                if (buffer[0] != 2)   //type init response
                {
                    return;           //"response packet type wrong: want %d, got %d"
                }
                if (bufferRead != 92) //always this length! for type=2
                {
                    return;           //"response packet too short: want %d, got %d"
                }
                if (buffer[1] != 0 || buffer[2] != 0 || buffer[3] != 0)
                {
                    return; //"response packet has non-zero reserved fields"
                }
                var theirIndex = buffer.LittleEndianToUInt32(4);
                var ourIndex   = buffer.LittleEndianToUInt32(8);
                if (ourIndex != 28)
                {
                    return; //log.Fatalf("response packet index wrong: want %d, got %d", 28, ourIndex)
                }
                var span = new Span <byte>(buffer);
                var(bytesRead, handshakeHash, transport) = hs.ReadMessage(span.Slice(12, 48),
                                                                          span.Slice(100)); //write on same buffer behind the received package (which
                if (bytesRead != 0)
                {
                    return; //"unexpected payload: %x"
                }
                var icmpHeader = new IcmpHeader()
                {
                    Type = 8, Id = 921, Sequence = 438
                };
                var pingMessage = icmpHeader.GetProtocolPacketBytes(Encoding.UTF8.GetBytes("WireGuard"));
                var pingHeader  = new Ipv4Header()
                {
                    Version            = 4, Length = 20, TotalLength = (ushort)(20 + pingMessage.Length),
                    Protocol           = 1, Ttl = 20,
                    SourceAddress      = new IPAddress(new byte[] { 10, 189, 129, 2 }),
                    DestinationAddress = new IPAddress(new byte[] { 10, 189, 129, 1 })
                }.GetProtocolPacketBytes(new byte[0]);


                span[0] = 4;
                span.Slice(1, 3).Assign((byte)0);
                theirIndex.ToLittleEndian(buffer, 4);
                0L.ToLittleEndian(buffer, 8);                                                        //this is the counter, little endian u64
                bytesWritten = transport.WriteMessage(
                    pingHeader.Concat(pingMessage).Concat(Enumerable.Repeat((byte)0, 11)).ToArray(), //pad message with 0 to make mod 16=0
                    span.Slice(16));

                //using (var streamWriter = new BinaryWriter(socket.OutputStream.AsStreamForWrite()))
                streamWriter.Write(span.Slice(0, 16 + bytesWritten).ToArray());
                streamWriter.Flush();
                successful = autoResetEvent.WaitOne(5000);
                if (!successful)
                {
                    return;
                }

                if (buffer[0] != 4)
                {
                    return;//"response packet type wrong: want %d, got %d"
                }
                if (buffer[1] != 0 || buffer[2] != 0 || buffer[3] != 0)
                {
                    return; //"response packet has non-zero reserved fields"
                }
                var replyPacket = buffer2.AsSpan(0, transport.ReadMessage(span.Slice(16, bufferRead - 16), buffer2));
                if (replyPacket.Length != 48)
                {
                    return;
                }

                var replyHeaderLen     = ((int)(replyPacket[0] & 0x0f)) << 2;
                var replyLen           = buffer2.BigEndianToUInt16(2);
                var our_index_received = buffer.LittleEndianToUInt32(4);
                if (our_index_received != 28)
                {
                    return;
                }
                var nonce = buffer2.LittleEndianToUInt64(8);
                //if (nonce != 0)//not parsed correctly?
                //    return;
                var replyMessage = IcmpHeader.Create(buffer2.AsSpan(replyHeaderLen, replyLen - replyHeaderLen).ToArray(), ref bytesRead);
                if (replyMessage.Type != 0 || replyMessage.Code != 0)
                {
                    return;
                }
                if (replyMessage.Id != 921 || replyMessage.Sequence != 438)
                {
                    return;
                }
                var replyPayload = Encoding.UTF8.GetString(buffer2.AsSpan(replyLen - replyHeaderLen + bytesRead, replyHeaderLen - bytesRead));
                if (replyPayload != "WireGuard") //trim necessary?
                {
                    return;
                }
            }
        }
예제 #13
0
    public void KatBlake2sKeyed(KatEntry ka)
    {
        var hash = compute(Blake2s.CreateIncrementalHasher(ka.Key), ka.Data);

        Assert.True(hash.SequenceEqual(ka.Digest));
    }
예제 #14
0
        internal static ResponseBlock Parse(byte[] bytes)
        {
            try
            {
                if (bytes == null)
                {
                    return(new ResponseBlock()
                    {
                        Success = false, Message = "Input bytes array is null"
                    });
                }

                using (BinaryReader bin = new BinaryReader(new MemoryStream(bytes)))
                {
                    int   hashing_len = 0;
                    Block block       = new Block();
                    block.Version = bin.ReadByte();
                    int len = bin.ReadByte();
                    if (len != Primitives.HashSize)
                    {
                        return(new ResponseBlock()
                        {
                            Success = false, Message = "The hash size is not equal"
                        });
                    }
                    block.PreviousHash = new Primitives.Hash {
                        Value = bin.ReadBytes(len)
                    };
                    block.Sequence = bin.ReadUInt64();

                    // user fields
                    int cnt = (int)bin.ReadByte();
                    if (cnt > 0)
                    {
                        block.UserFields = new List <UserField>();
                        for (int i = 0; i < cnt; i++)
                        {
                            block.UserFields.Add(UserField.Parse(bin));
                        }
                    }

                    // round cost
                    block.RoundCost          = new Money();
                    block.RoundCost.Integral = bin.ReadInt32();
                    block.RoundCost.Fraction = bin.ReadUInt64();

                    // transactions
                    cnt = (int)bin.ReadUInt32();
                    if (cnt > 0)
                    {
                        block.Transactions = new List <Transaction>();
                        for (int i = 0; i < cnt; i++)
                        {
                            block.Transactions.Add(Transaction.Parse(bin));
                        }

                        // round cost clarify
                        if (block.RoundCost.IsZero)
                        {
                            foreach (var t in block.Transactions)
                            {
                                block.RoundCost += t.ActualFee;
                            }
                        }
                    }

                    // new wallets
                    cnt = (int)bin.ReadUInt32();
                    if (cnt > 0)
                    {
                        block.IntroducedWallets = new List <WalletIntroduce>();
                        for (int i = 0; i < cnt; i++)
                        {
                            WalletIntroduce w = new WalletIntroduce();
                            Int64           v = bin.ReadInt64();
                            if (v < 0)
                            {
                                v = -v;
                                // address is target
                                if (v < block.Transactions.Count)
                                {
                                    w.Key = block.Transactions[(int)v].Target;
                                }
                            }
                            else
                            {
                                if (v < block.Transactions.Count)
                                {
                                    w.Key = block.Transactions[(int)v].Source;
                                }
                            }
                            w.Id = bin.ReadUInt32();
                            block.IntroducedWallets.Add(w);
                        }
                    }

                    // consensus info

                    // current RT
                    cnt = (int)(uint)bin.ReadByte();
                    UInt64 bits_trusted = bin.ReadUInt64(); // count of "1" = sig_blk_cnt
                    if (cnt > 0)
                    {
                        block.TrustedNodes = new List <ConsensusMember>();
                        for (int i = 0; i < cnt; i++)
                        {
                            block.TrustedNodes.Add(new ConsensusMember()
                            {
                                Id = new Primitives.PublicKey {
                                    Value = bin.ReadBytes(Primitives.PublicKeySize)
                                }
                            });
                        }
                    }

                    // previous consensus
                    cnt = (int)(uint)bin.ReadByte();
                    if (cnt > 0)
                    {
                        block.TrustedApproval = new List <KeyValuePair <int, Primitives.Signature> >();
                        UInt64 bits_appr       = bin.ReadUInt64();
                        int    sig_prev_rt_cnt = CountBits(bits_appr);
                        int    isig            = 0;
                        for (int i = 0; i < cnt; i++)
                        {
                            if ((bits_appr & (0x1UL << i)) == 0)
                            {
                                continue;
                            }
                            if (isig >= sig_prev_rt_cnt)
                            {
                                break;
                            }
                            block.TrustedApproval.Add(new KeyValuePair <int, Primitives.Signature>(
                                                          isig,
                                                          new Primitives.Signature {
                                Value = bin.ReadBytes(Primitives.SignatureSize)
                            }
                                                          ));
                            isig++;
                        }
                        if (isig != sig_prev_rt_cnt)
                        {
                            //TODO: malformed trusted approval section
                        }
                    }

                    hashing_len = (int)(uint)bin.ReadUInt64();

                    // continue read block.TrustedNodes (signatures)
                    cnt = block.TrustedNodes.Count;
                    for (int i = 0; i < cnt; i++)
                    {
                        if ((bits_trusted & (0x1UL << i)) == 0)
                        {
                            continue;
                        }
                        block.TrustedNodes[i].Signature = new Primitives.Signature()
                        {
                            Value = bin.ReadBytes(Primitives.SignatureSize)
                        };
                    }

                    // contract signatures
                    cnt = (int)(uint)bin.ReadByte();
                    if (cnt > 0)
                    {
                        block.ContractsApproval = new List <ContractConfirmation>();
                        for (int i = 0; i < cnt; i++)
                        {
                            block.ContractsApproval.Add(ContractConfirmation.Parse(bin));
                        }
                    }

                    if (bin.BaseStream.Position == bin.BaseStream.Length)
                    {
                        if (hashing_len > 0)
                        {
                            block.Hash = new Primitives.Hash()
                            {
                                Value = Blake2s.ComputeHash(Primitives.HashSize, bytes.AsSpan(0, hashing_len))
                            };
                        }
                        return(new ResponseBlock()
                        {
                            Success = true, Block = block
                        });
                    }

                    return(new ResponseBlock()
                    {
                        Success = false, Message = "The stream postion is not equal to the stream length"
                    });
                }
            }
            catch (Exception ex)
            {
                return(new ResponseBlock()
                {
                    Success = false, Message = ex.Message
                });
            }
        }
        public Transaction InitTransaction(RequestApiModel model)
        {
            Transaction transac = new Transaction();

            using (var client = GetClientByModel(model))
            {
                // отправитель
                var sourceByte = SimpleBase.Base58.Bitcoin.Decode(model.PublicKey);
                transac.Source = sourceByte.ToArray();

                if (model.Fee == 0)
                {
                    Decimal res;
                    if (!string.IsNullOrWhiteSpace(model.FeeAsString) && Decimal.TryParse(model.FeeAsString.Replace(",", "."), NumberStyles.Any, CultureInfo.GetCultureInfo("en-US"), out res))
                    {
                        transac.Fee = BCTransactionTools.EncodeFeeFromDouble(Decimal.ToDouble(res));
                    }
                    else
                    {
                        transac.Fee = BCTransactionTools.EncodeFeeFromDouble(Decimal.ToDouble(model.Fee));
                    }
                }
                else
                {
                    transac.Fee = BCTransactionTools.EncodeFeeFromDouble(Decimal.ToDouble(model.Fee));
                }

                //transac.Fee = BCTransactionTools.EncodeFeeFromDouble(Decimal.ToDouble(model.Fee));

                transac.Currency = 1;
                // ЗАПРОС механизм присваивания транзакции
                transac.Id = client.WalletDataGet(sourceByte.ToArray()).WalletData.LastTransactionId + 1;
                if (!String.IsNullOrEmpty(model.UserData))
                {
                    transac.UserFields = SimpleBase.Base58.Bitcoin.Decode(model.UserData).ToArray();
                }
                //  transac.UserFields = Convert.FromBase64String(model.UserData);

                if (model.MethodApi == ApiMethodConstant.TransferCs)
                {
                    if (model.Amount == 0)
                    {
                        if (string.IsNullOrEmpty(model.AmountAsString))
                        {
                            transac.Amount = new Amount();
                        }
                        else
                        {
                            Decimal res;
                            if (Decimal.TryParse(model.AmountAsString.Replace(",", "."), NumberStyles.Any, CultureInfo.GetCultureInfo("en-US"), out res))
                            {
                                transac.Amount = BCTransactionTools.GetAmountByDouble_C(res);
                            }
                            else
                            {
                                transac.Amount = BCTransactionTools.GetAmountByDouble_C(model.Amount);
                            }
                        }
                    }
                    else
                    {
                        transac.Amount = BCTransactionTools.GetAmountByDouble_C(model.Amount);
                    }

                    if (model.Fee == 0)
                    {
                        var minFee = MinTransactionFee;
                        if (model.Amount - minFee >= 0.0M)
                        {
                            model.Fee    = minFee;
                            model.Amount = model.Amount - minFee;
                            //GetActualFee(RequestFeeModel)
                            //ServiceProvider.GetService<MonitorService>().GetBalance(model);

                            transac.Fee    = BCTransactionTools.EncodeFeeFromDouble(Convert.ToDouble(minFee));
                            transac.Amount = BCTransactionTools.GetAmountByDouble_C(model.Amount);
                        }
                        else
                        {
                            throw new Exception("Fee is zero and couldn't be get from transaction sum");
                        }
                    }
                    transac.Target = SimpleBase.Base58.Bitcoin.Decode(model.ReceiverPublicKey).ToArray();
                }
                else if (model.MethodApi == ApiMethodConstant.SmartDeploy)
                {
                    transac.Amount = BCTransactionTools.GetAmountByDouble_C(0);
                    //  Byte[] byteSource = sourceByte;
                    IEnumerable <Byte> sourceCodeByte = sourceByte.ToArray();

                    sourceCodeByte = sourceCodeByte.Concat(BitConverter.GetBytes(transac.Id).Take(6));
                    // ЗАПРОС
                    var byteCodes =
                        client.SmartContractCompile(model.SmartContractSource);
                    if (byteCodes.Status.Code > 0)
                    {
                        throw new Exception(byteCodes.Status.Message);
                    }
                    foreach (var item in byteCodes.ByteCodeObjects)
                    {
                        sourceCodeByte = sourceCodeByte.Concat(item.ByteCode);
                    }

                    transac.Target        = Blake2s.ComputeHash(sourceCodeByte.ToArray());
                    transac.SmartContract = new SmartContractInvocation()
                    {
                        SmartContractDeploy = new SmartContractDeploy()
                        {
                            SourceCode      = model.SmartContractSource,
                            ByteCodeObjects = byteCodes.ByteCodeObjects
                        },
                    };
                }
                else if (model.MethodApi == ApiMethodConstant.SmartMethodExecute)
                {
                    var listParam      = new List <Variant>();
                    var contractParams = new List <TokenParamsApiModel>();
                    if (model.ContractParams.Count > model.TokenParams.Count)
                    {
                        foreach (var item in model.ContractParams)
                        {
                            var param = new Variant();

                            if (item.ValBool != null)
                            {
                                param.V_boolean = item.ValBool.Value;
                            }
                            else if (item.ValDouble != null)
                            {
                                param.V_double = item.ValDouble.Value;
                            }
                            else if (item.ValInt != null)
                            {
                                param.V_int = item.ValInt.Value;
                            }
                            else if (item.ValInt != null)
                            {
                                param.V_int = item.ValInt.Value;
                            }
                            else
                            {
                                param.V_string = item.ValString;
                            }
                            listParam.Add(param);
                        }
                    }
                    else
                    {
                        foreach (var item in model.TokenParams)
                        {
                            var param = new Variant();

                            if (item.ValBool != null)
                            {
                                param.V_boolean = item.ValBool.Value;
                            }
                            else if (item.ValDouble != null)
                            {
                                param.V_double = item.ValDouble.Value;
                            }
                            else if (item.ValInt != null)
                            {
                                param.V_int = item.ValInt.Value;
                            }
                            else if (item.ValInt != null)
                            {
                                param.V_int = item.ValInt.Value;
                            }
                            else
                            {
                                param.V_string = item.ValString;
                            }
                            listParam.Add(param);
                        }
                    }


                    transac.Amount = BCTransactionTools.GetAmountByDouble_C(0); // количество токенов фиксируем в параметрах
                    if (model.ContractPublicKey == null || model.ContractPublicKey == "")
                    {
                        transac.Target = SimpleBase.Base58.Bitcoin.Decode(model.TokenPublicKey).ToArray(); // в таргет публичный ключ Token
                    }
                    else
                    {
                        transac.Target = SimpleBase.Base58.Bitcoin.Decode(model.ContractPublicKey).ToArray(); // в таргет публичный ключ Contract
                    }

                    transac.SmartContract = new SmartContractInvocation()
                    {
                        Method = (model.ContractMethod == null || model.ContractMethod == "") ? model.TokenMethod : model.ContractMethod,
                        Params = listParam
                    };
                }
                else if (model.MethodApi == ApiMethodConstant.TransferToken)
                {
                    transac.Amount        = BCTransactionTools.GetAmountByDouble_C(0);                        // количество токенов фиксируем в параметрах
                    transac.Target        = SimpleBase.Base58.Bitcoin.Decode(model.TokenPublicKey).ToArray(); // в таргет публичный ключ токена
                    transac.SmartContract = new SmartContractInvocation()
                    {
                        Method = "transfer",
                        Params = new List <Variant>()
                        {
                            new Variant()
                            {
                                // адресат перевода
                                V_string = model.ReceiverPublicKey
                            },
                            new Variant()
                            {
                                V_string = model.Amount.ToString().Replace(",", ".")
                            }
                        }
                    };
                }
            }

            return(transac);
        }