public static RelayReceipt FromBytes(byte[] bytes)
 {
     using (var stream = new MemoryStream(bytes))
     {
         using (var reader = new BinaryReader(stream))
         {
             var receipt = new RelayReceipt();
             receipt.UnserializeData(reader);
             return(receipt);
         }
     }
 }
        public void SettleChannel(RelayReceipt receipt)
        {
            var channelIndex = GetIndex(receipt.message.sender, receipt.message.receiver);

            // check for possible replay attack
            Runtime.Expect(receipt.message.nexus == Runtime.NexusName, "invalid nexus name");

            // here we count how many receipts we are implicitly accepting
            // this means that we don't need to accept every receipt, allowing skipping several
            var receiptCount = 1 + receipt.message.index - channelIndex;

            Runtime.Expect(receiptCount > 0, "invalid receipt index");

            var expectedFee = RelayFeePerMessage * receiptCount;

            var balance = GetBalance(receipt.message.sender);

            Runtime.Expect(balance >= expectedFee, "insuficient balance");

            var bytes = receipt.message.ToByteArray();

            Runtime.Expect(receipt.signature.Verify(bytes, receipt.message.sender), "invalid signature");

            balance -= expectedFee;
            _balances.Set <Address, BigInteger>(receipt.message.sender, balance);
            var key = MakeKey(receipt.message.sender, receipt.message.receiver);

            _indices.Set <string, BigInteger>(key, receipt.message.index + 1);

            Runtime.Expect(expectedFee > 0, "invalid payout");

            var payout = expectedFee / 2;

            // send half to the chain
            Runtime.TransferTokens(DomainSettings.FuelTokenSymbol, this.Address, this.Address, payout);

            // send half to the receiver
            Runtime.TransferTokens(DomainSettings.FuelTokenSymbol, this.Address, receipt.message.receiver, payout);

            Runtime.Notify(EventKind.ChannelSettle, receipt.message.sender, receiptCount);
        }