/// <summary>
        /// Extract ConsentAction information from OP_RETURN part
        /// </summary>
        /// <param name="transaction">The transaction to be extracted information from</param>
        /// <returns>If information is present, ConsentAction object is returned. Otherwise, null is returned.</returns>
        public static ConsentAction AsConsentAction(this ApiTransaction transaction)
        {
            try
            {
                var ca        = new ConsentAction();
                var op_return = transaction.GetOP_RETURN();
                if (string.IsNullOrEmpty(op_return) || !op_return.StartsWith("43504d4f2d5448"))
                {
                    return(null);
                }

                var firstIndex = op_return.IndexOf("3a");
                ca.Domain = Encoding.ASCII.GetString(FromHex(op_return.Substring(0, firstIndex)));
                var secondIndex = op_return.IndexOf("3a", firstIndex + 2);
                var action      = Encoding.ASCII.GetString(FromHex(op_return.Substring(firstIndex + 2, secondIndex - firstIndex - 2)));
                ca.DocumentHash = op_return.Substring(secondIndex + 2);

                if (ca.DocumentHash.Length > 64)
                {
                    return(null);
                }

                if (action == "ASK")
                {
                    ca.AskFrom     = transaction.vin[0].addr;
                    ca.AskTxId     = transaction.txid;
                    ca.AskTick     = transaction.blocktime;
                    ca.ApproveFrom = transaction.vout.First(v => v.scriptPubKey.addresses != null && v.scriptPubKey.addresses[0] != ca.AskFrom).scriptPubKey.addresses[0];
                    return(ca);
                }
                else if (action == "APPROVE")
                {
                    ca.ApproveFrom  = transaction.vin[0].addr;
                    ca.AskFrom      = transaction.vout.First(v => v.scriptPubKey.addresses != null && v.scriptPubKey.addresses[0] != ca.AskFrom).scriptPubKey.addresses[0];
                    ca.ApproveTxId  = transaction.txid;
                    ca.ApprovedTick = transaction.blocktime;
                    return(ca);
                }
                else
                {
                    return(null);
                }
            }
            catch (Exception)
            {
                return(null);
            }
        }
        public static Ledger ToLedger(this ApiTransaction transaction, WalletContract contract, ContractService service)
        {
            var ledger = new Ledger()
            {
                TxId        = transaction.txid,
                Blockheight = transaction.blockheight,
                Time        = new DateTime(1970, 1, 1).AddSeconds(transaction.blocktime)
            };
            var domain = BitConverter.ToString(Encoding.Default.GetBytes("RMUTSB.AC.TH")).Replace("-", "").ToLower();
            //var domain = "54534357414c4c4554";
            var data = transaction.GetOP_RETURN();

            try
            {
                if (data.StartsWith(domain))
                {
                    return(null);
                }
                var contractNameHex = data.Substring(0, 16);
                if (contract.NameHex == contractNameHex)
                {
                    ledger.Operation = (OperationCode)(ushort.Parse(data.Substring(16, 4), System.Globalization.NumberStyles.HexNumber));
                    var publicAddress = transaction.vin.First(v => !string.IsNullOrEmpty(v.addr)).addr;
                    var publicKey     = new BitcoinPubKeyAddress(publicAddress, service.MainNetwork);
                    ledger.TokenSenderHash      = publicKey.ExtractWitnessProgram();
                    ledger.TokenReceiverHashHex = data.Substring(20, 40);
                    ledger.Amount = BitConverterExtension.ToDecimal(data.Substring(60, 32).StringToByteArray());
                    if (data.Length > 92)
                    {
                        ledger.ReferenceCode = Encoding.Default.GetString(data.Substring(92).StringToByteArray());
                    }
                    return(ledger);
                }
                else
                {
                    return(null);
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
                return(null);
            }
        }