2020-05-18 15:06:12 +00:00
|
|
|
/*
|
|
|
|
Package storage provides functions to access and modify contract's storage.
|
|
|
|
Neo storage's model follows simple key-value DB pattern, this storage is a part
|
|
|
|
of blockchain state, so you can use it between various invocations of the same
|
|
|
|
contract.
|
|
|
|
*/
|
2018-08-20 11:22:46 +00:00
|
|
|
package storage
|
|
|
|
|
2021-02-05 16:02:09 +00:00
|
|
|
import (
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/interop/iterator"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/interop/neogointernal"
|
|
|
|
)
|
2018-08-31 08:23:57 +00:00
|
|
|
|
2020-05-18 15:06:12 +00:00
|
|
|
// Context represents storage context that is mandatory for Put/Get/Delete
|
|
|
|
// operations. It's an opaque type that can only be created properly by
|
2020-05-18 15:13:45 +00:00
|
|
|
// GetContext, GetReadOnlyContext or ConvertContextToReadOnly. It's similar
|
|
|
|
// to Neo .net framework's StorageContext class.
|
2018-08-21 07:11:25 +00:00
|
|
|
type Context struct{}
|
2018-08-20 11:22:46 +00:00
|
|
|
|
2021-01-12 10:39:31 +00:00
|
|
|
// FindFlags represents parameters to `Find` iterator.
|
|
|
|
type FindFlags byte
|
|
|
|
|
|
|
|
const (
|
|
|
|
// None is default option. Iterator values are key-value pairs.
|
|
|
|
None FindFlags = 0
|
|
|
|
// KeysOnly is used for iterating over keys.
|
|
|
|
KeysOnly FindFlags = 1 << 0
|
2021-12-06 15:06:34 +00:00
|
|
|
// RemovePrefix is used for stripping prefix (passed to Find) from keys.
|
2021-01-12 10:39:31 +00:00
|
|
|
RemovePrefix FindFlags = 1 << 1
|
|
|
|
// ValuesOnly is used for iterating over values.
|
|
|
|
ValuesOnly FindFlags = 1 << 2
|
2021-01-12 12:09:05 +00:00
|
|
|
// DeserializeValues is used for deserializing values on-the-fly.
|
|
|
|
// It can be combined with other options.
|
|
|
|
DeserializeValues FindFlags = 1 << 3
|
2021-01-12 12:32:27 +00:00
|
|
|
// PickField0 is used to get first field in a serialized struct or array.
|
|
|
|
PickField0 FindFlags = 1 << 4
|
|
|
|
// PickField1 is used to get second field in a serialized struct or array.
|
|
|
|
PickField1 FindFlags = 1 << 5
|
2023-03-24 16:32:06 +00:00
|
|
|
// Backwards is used to iterate over elements in reversed (descending) order.
|
|
|
|
Backwards FindFlags = 1 << 7
|
2021-01-12 10:39:31 +00:00
|
|
|
)
|
|
|
|
|
2020-05-18 15:13:45 +00:00
|
|
|
// ConvertContextToReadOnly returns new context from the given one, but with
|
|
|
|
// writing capability turned off, so that you could only invoke Get and Find
|
|
|
|
// using this new Context. If Context is already read-only this function is a
|
2020-06-10 08:55:56 +00:00
|
|
|
// no-op. It uses `System.Storage.AsReadOnly` syscall.
|
2021-02-05 16:02:09 +00:00
|
|
|
func ConvertContextToReadOnly(ctx Context) Context {
|
2021-03-04 08:51:32 +00:00
|
|
|
return neogointernal.Syscall1("System.Storage.AsReadOnly", ctx).(Context)
|
2021-02-05 16:02:09 +00:00
|
|
|
}
|
2020-05-18 15:13:45 +00:00
|
|
|
|
2020-05-18 15:06:12 +00:00
|
|
|
// GetContext returns current contract's (that invokes this function) storage
|
2020-06-10 08:55:56 +00:00
|
|
|
// context. It uses `System.Storage.GetContext` syscall.
|
2021-02-05 16:02:09 +00:00
|
|
|
func GetContext() Context {
|
|
|
|
return neogointernal.Syscall0("System.Storage.GetContext").(Context)
|
|
|
|
}
|
2018-08-20 11:22:46 +00:00
|
|
|
|
2020-05-18 15:13:45 +00:00
|
|
|
// GetReadOnlyContext returns current contract's (that invokes this function)
|
|
|
|
// storage context in read-only mode, you can use this context for Get and Find
|
|
|
|
// functions, but using it for Put and Delete will fail. It uses
|
2020-06-10 08:55:56 +00:00
|
|
|
// `System.Storage.GetReadOnlyContext` syscall.
|
2021-02-05 16:02:09 +00:00
|
|
|
func GetReadOnlyContext() Context {
|
|
|
|
return neogointernal.Syscall0("System.Storage.GetReadOnlyContext").(Context)
|
|
|
|
}
|
2020-05-18 15:13:45 +00:00
|
|
|
|
2020-05-18 15:06:12 +00:00
|
|
|
// Put saves given value with given key in the storage using given Context.
|
2023-04-03 10:34:24 +00:00
|
|
|
// Even though it accepts interface{} hidden under `any` for both, you can only
|
|
|
|
// pass simple types there like string, []byte, int or bool (not structures or
|
|
|
|
// slices of more complex types). To put more complex types there serialize them
|
|
|
|
// first using runtime.Serialize. This function uses `System.Storage.Put` syscall.
|
|
|
|
func Put(ctx Context, key any, value any) {
|
2021-02-05 16:02:09 +00:00
|
|
|
neogointernal.Syscall3NoReturn("System.Storage.Put", ctx, key, value)
|
|
|
|
}
|
2018-08-20 11:22:46 +00:00
|
|
|
|
2020-05-18 15:06:12 +00:00
|
|
|
// Get retrieves value stored for the given key using given Context. See Put
|
2020-06-23 21:06:42 +00:00
|
|
|
// documentation on possible key and value types. If the value is not present in
|
|
|
|
// the database it returns nil. This function uses `System.Storage.Get` syscall.
|
2023-04-03 10:34:24 +00:00
|
|
|
func Get(ctx Context, key any) any {
|
2021-02-05 16:02:09 +00:00
|
|
|
return neogointernal.Syscall2("System.Storage.Get", ctx, key)
|
|
|
|
}
|
2018-08-20 11:22:46 +00:00
|
|
|
|
2020-05-18 15:06:12 +00:00
|
|
|
// Delete removes key-value pair from storage by the given key using given
|
|
|
|
// Context. See Put documentation on possible key types. This function uses
|
2020-06-10 08:55:56 +00:00
|
|
|
// `System.Storage.Delete` syscall.
|
2023-04-03 10:34:24 +00:00
|
|
|
func Delete(ctx Context, key any) {
|
2021-02-05 16:02:09 +00:00
|
|
|
neogointernal.Syscall2NoReturn("System.Storage.Delete", ctx, key)
|
|
|
|
}
|
2018-08-20 11:22:46 +00:00
|
|
|
|
2020-05-18 15:06:12 +00:00
|
|
|
// Find returns an iterator.Iterator over key-value pairs in the given Context
|
|
|
|
// that match the given key (contain it as a prefix). See Put documentation on
|
|
|
|
// possible key types and iterator package documentation on how to use the
|
2020-06-10 08:55:56 +00:00
|
|
|
// returned value. This function uses `System.Storage.Find` syscall.
|
2023-04-03 10:34:24 +00:00
|
|
|
func Find(ctx Context, key any, options FindFlags) iterator.Iterator {
|
2021-02-05 16:02:09 +00:00
|
|
|
return neogointernal.Syscall3("System.Storage.Find", ctx, key, options).(iterator.Iterator)
|
2021-01-12 10:39:31 +00:00
|
|
|
}
|