static UInt160 ToUInt160(Neo.VM.Types.StackItem item)
        {
            if (item.Type != Neo.VM.Types.StackItemType.ByteString)
            {
                throw new Exception($"Unexpected result stack type {item.Type}");
            }

            if (item.GetSpan().Length != UInt160.Length)
            {
                throw new Exception($"Unexpected result stack length {item.GetSpan().Length}");
            }

            return(new UInt160(item.GetSpan()));
        }
        static UInt160 ToUInt160(Neo.VM.Types.StackItem item)
        {
            if (item.IsNull)
            {
                return(UInt160.Zero);
            }

            var bytes = item.GetSpan();

            return(bytes.Length == 0
                ? UInt160.Zero
                : bytes.Length == 20
                    ? new UInt160(bytes)
                    : throw new ArgumentException("invalid UInt160", nameof(item)));
        }
        static int GetSize(Neo.VM.Types.StackItem item, uint maxSize)
        {
            int size         = 0;
            var serialized   = new List <Neo.VM.Types.CompoundType>();
            var unserialized = new Stack <Neo.VM.Types.StackItem>();

            unserialized.Push(item);
            while (unserialized.Count > 0)
            {
                item = unserialized.Pop();
                size++;
                switch (item)
                {
                case Neo.VM.Types.Null _:
                    break;

                case Neo.VM.Types.Boolean _:
                    size += sizeof(bool);
                    break;

                case Neo.VM.Types.Integer _:
                case Neo.VM.Types.ByteString _:
                case Neo.VM.Types.Buffer _:
                {
                    var span = item.GetSpan();
                    size += Neo.IO.Helper.GetVarSize(span.Length);
                    size += span.Length;
                }
                break;

                case Neo.VM.Types.Array array:
                    if (serialized.Any(p => ReferenceEquals(p, array)))
                    {
                        throw new NotSupportedException();
                    }
                    serialized.Add(array);
                    size += Neo.IO.Helper.GetVarSize(array.Count);
                    for (int i = array.Count - 1; i >= 0; i--)
                    {
                        unserialized.Push(array[i]);
                    }
                    break;

                case Neo.VM.Types.Map map:
                    if (serialized.Any(p => ReferenceEquals(p, map)))
                    {
                        throw new NotSupportedException();
                    }
                    serialized.Add(map);
                    size += Neo.IO.Helper.GetVarSize(map.Count);
                    foreach (var pair in map.Reverse())
                    {
                        unserialized.Push(pair.Value);
                        unserialized.Push(pair.Key);
                    }
                    break;

                default:
                    throw new NotSupportedException();
                }
            }

            if (size > maxSize)
            {
                throw new InvalidOperationException();
            }
            return(size);
        }