Ensure star type assertion is handled properly #1228

Open
opened 2025-12-28 17:15:41 +00:00 by sami · 2 comments
Owner

Originally created by @AnnaShaleva on GitHub (Dec 4, 2023).

Suppose we have a structure declared in the contract:

type (
	UserKey struct {
		Address interop.Hash160
		Data    []byte
		Role    int
	}
)

And suppose we have the following method:

func GetUserKey(ctx storage.Context, idKey []byte) *UserKey {
	data := storage.Get(ctx, idKey)
	if data != nil {
		return std.Deserialize(data.([]byte)).(*UserKey)
	}

	return nil
}

The result of compilation is invalid script:

    compile.go:55: 
        	Error Trace:	/home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/neotest/compile.go:55
        	            				/home/anna/Documents/GitProjects/nspcc-dev/console/internal/contract/usermanagement/usermanagement_contract_test.go:17
        	            				/home/anna/Documents/GitProjects/nspcc-dev/console/internal/contract/usermanagement/usermanagement_contract_test.go:24
        	Error:      	Received unexpected error:
        	            	using type ANY is incorrect at offset 275

The wrong line is the conversion of structure got after std.Deserialize to Any (which is the pointer to UserKey).

Describe the solution you'd like

The desired result is to convert the structure got after std.Deserialize directly to the UserKey structure if it's not nil. The case is that this code is very similar to the one that we have in our interop package:
nspcc-dev/neo-go@9a270ae30c/pkg/interop/native/ledger/ledger.go (L42-L44)
However, the interop API works fine.

Originally created by @AnnaShaleva on GitHub (Dec 4, 2023). ## Is your feature request related to a problem? Please describe. Suppose we have a structure declared in the contract: ``` type ( UserKey struct { Address interop.Hash160 Data []byte Role int } ) ``` And suppose we have the following method: ``` func GetUserKey(ctx storage.Context, idKey []byte) *UserKey { data := storage.Get(ctx, idKey) if data != nil { return std.Deserialize(data.([]byte)).(*UserKey) } return nil } ``` The result of compilation is invalid script: ``` compile.go:55: Error Trace: /home/anna/Documents/GitProjects/nspcc-dev/neo-go/pkg/neotest/compile.go:55 /home/anna/Documents/GitProjects/nspcc-dev/console/internal/contract/usermanagement/usermanagement_contract_test.go:17 /home/anna/Documents/GitProjects/nspcc-dev/console/internal/contract/usermanagement/usermanagement_contract_test.go:24 Error: Received unexpected error: using type ANY is incorrect at offset 275 ``` The wrong line is the conversion of structure got after `std.Deserialize` to `Any` (which is the pointer to `UserKey`). ## Describe the solution you'd like The desired result is to convert the structure got after `std.Deserialize` directly to the `UserKey` structure if it's not nil. The case is that this code is very similar to the one that we have in our interop package: https://github.com/nspcc-dev/neo-go/blob/9a270ae30cb889ecbc346efc2efa1d1b6c408abd/pkg/interop/native/ledger/ledger.go#L42-L44 However, the interop API works fine.
Author
Owner

@roman-khimov commented on GitHub (Dec 4, 2023):

Interops are inlined and IIRC there is some special code to handle interop data types, but in general your example should work, so it's just a bug in pointer handling.

@roman-khimov commented on GitHub (Dec 4, 2023): Interops are inlined and IIRC there is some special code to handle interop data types, but in general your example should work, so it's just a bug in pointer handling.
Author
Owner

@roman-khimov commented on GitHub (Sep 12, 2024):

The workaround from https://github.com/nspcc-dev/neo-go/issues/3580#issuecomment-2341916070 doesn't really work, btw (nothing is copied, NULLs are left in the struct). Field-by-field assignments do work.

@roman-khimov commented on GitHub (Sep 12, 2024): The workaround from https://github.com/nspcc-dev/neo-go/issues/3580#issuecomment-2341916070 doesn't really work, btw (nothing is copied, NULLs are left in the struct). Field-by-field assignments do work.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
nspcc-dev/neo-go#1228
No description provided.