-
Notifications
You must be signed in to change notification settings - Fork 113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft NEP 25: Extended types for NEP-14 #160
Conversation
🥇
Yeah I think these are a must. I had to read the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am very much in favor of this proposal, but it needs to be combined with the changes proposed in #151. In particular, I think this proposal needs a syntax-independent description of the extended type semantics. Something similar to the ContractType Type Model section of #151.
Note, I don't care if the eventual proposal uses the string encoding from #151 (Array<Hash160>
) or JSON encoding from this proposal ({"type": "Array", "value": {"type": "Hash160"}}
). Whatever the group at large decides to support for this proposal, debug info v2 will adopt.
I only see |
A few nitpicks:
|
It is true that the way #151 encodes Struct types would be a NEP-14 breaking change. But the semantics of #151 structs is not a breaking change. The semantics of encoding a struct param as I asked for this PR to include a syntax-independent description of the extended type system to ensure that the extended type system works for both contract client code generation and better debugger experience. Once we nail down the semantics of the extended type system, we can choose a syntax that is backwards compatible. Your point about Iterator is spot on. #151 defines semantics for Interop ContractType, but didn't originally include any specific semantics for Iterators. Given their importance, this is an oversight in #151 that I recently addressed but haven't implemented yet. Having a syntax-independent description of the type system allows us to have discussions like "What information do we need about Interop parameters for code gen + debugger purposes?" without getting bogged down on how this stuff is encoded. BTW, Address is just an alias for Hash160 so it wouldn't break NEP-14 back compat. As you point out, "any Hash160 can be an address, it's just a matter of representation". Hash160 representation may not affect contract client code gen but it definitely affects debugger representation. The same way this proposal adds extended fields to more fully describe |
Technically, we can have non-struct things in
A string will need to be parsed, while we can have the same JSON structures representing all of this directly (maybe some depth limit is necessary though, but I've tested things like |
True, the main thing of course is to settle on the exact details we want/need to express.
Do we have any |
When we first built the debugger, I was concerned about debug info size. Hence we chose a compact CSV-style string representation instead of separate JSON fields. But that concern has proven to be somewhat overblown.
If you add the semantic type system details to this document, then I will be able to leverage that for the advanced debug information. As I said, I'd be happy to update the debug info proposal to support JSON serialization for type information in order to bring it more inline with how the manifest is serialized. That should make producing debug info easier for language teams.
Contract Hashes are Hash160s values but are typically not treated as an address. |
@roman-khimov Any progress on including the type system info from #151 into this NEP? |
I'm waiting for more feedback on "things intentionally omitted for now" and other general topics, "Address" (as a representation hint for Hash160) can be added as well if it's OK for us to have representation details at this level (it's OK for me, but maybe there are some objections). BTW, as I've said earlier, we have JSON-RPC SDK generator that uses similar data to create (Go) client-side code that will then work via regular Neo JSON-RPC. It works fine for backend code, but we also have something for frontend in the queue. It's a different experimental thing that automatically provides server-side contract-specific RESTful APIs using similar ABI data, this then makes it trivial for JS clients to access contract methods. |
Looking forward to the next revision after you get more feedback.
There's a similar tool in Neo.BuildTools that generates a C# interface from the current manifest file. THis interface is currently only used in C# test methods, but could also be used for generating client APIs as well. I've had similar thoughts to generating these APIs from the extended type info in the prototype v2 debug info. However, I would MUCH rather this extended type info in the manifest. |
Interesting proposal to have all types checked. Regarding syntax, do you think some shorter "template-based" version like: Original:
Possibility with template-based syntax embedded directly on the string:
Is this the intention, right? It's smaller, but do you think it makes it much harder to parse? (some extra code will be needed for angle brackets) |
It's more like
|
Neo Debug Info v2 uses a single string like @igormcoelho asked about. But I agree with @roman-khimov that a mechanism that is easier to parse is probably easier to get adopted across the community |
This is a very interesting proposal, in fact, before knowing about this proposal, @meevee98, @luc10921 and I were working on something similar to this. We implemented a few "hints" generated by neo3-boa (PR link) that can be used by neo3-parser (PR link). For instance, if a method is implemented like this: @public
def Main(var: Dict[str, List[bool]]) -> List[Union[Dict[str, int], str, bool]]:
if var:
return []
return [] Neo3-boa will compile the manifest to something like this: {
"name": "ManifestTypeHintMapsArraysUnionHint",
"groups": [],
"abi": {
"methods": [
{
"name": "Main",
"offset": 0,
"parameters": [
{
"type": "Map",
"generickey": {
"type": "String"
},
"genericitem": {
"type": "Array",
"generic": {
"type": "Boolean"
}
},
"name": "var"
}
],
"safe": false,
"returntype": "Array",
"returngeneric": {
"type": "Any",
"union": [
{
"type": "String"
},
{
"type": "Map",
"generickey": {
"type": "String"
},
"genericitem": {
"type": "Integer"
}
},
{
"type": "Boolean"
}
]
}
}
],
"events": []
},
"permissions": [
{
"contract": "*",
"methods": "*"
}
],
"trusts": [],
"features": {},
"supportedstandards": [],
"extra": null
} There are only 5 new keys to indicate the extended types: The possible "hints" are: Today this is saved on the manifest but when deploying to the blockchain this is lost. We have to manually copy this content from the manifest to neo3-parser as a So I am very excited by this proposal, even if it's decided a very different format than what we implemented. |
I'm back from vacation. Can we start making progress on this? |
Apparenty
I've seen no "new" feedback or objections since February (arguably March), I'd like to think that it has had enough time to provide input on and we should now accept it, unless @roman-khimov want's to add the "things intentionally ommitted for now" in this specific NEP in a new revision? |
As for "things intentionally ommitted for now", I don't see any specific opinions on that which to me means that there is no immediate need for any of them. They can be added in a future NEP update, so it shouldn't be a blocker. The only relevant unsolved feedback here is the address representation from @devhawk. I don't see any objection to it, so I'll update the proposal to include this data as well and consider it to be done for now. |
Which is easy for a regular type ( @devhawk, do we still need it? How do you differentiate between the two when generating manifest? |
As written there:
Any example that has all fields would be incorrect in some ways, so I doubt it can be improved.
Fixed!
Well, JSON is order-agnostic for object elements, so we can have it in any way, but to make it easier to read I've reordered some things. |
Can we address this as well as others in this |
Likely what was originally meant there is https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/identifier-names. But I don't know if there are any contracts now that go beyond this definition of identifier (which would raise compatibility question). We can fix it (to valid UTF-8 letters?), but only after mainnet/testnet check.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the json
should be json syntax highlighted
, no sense in using legacy markdown commands.
```json
Text here
```
Signed-off-by: Roman Khimov <[email protected]>
Signed-off-by: Roman Khimov <[email protected]>
Signed-off-by: Roman Khimov <[email protected]>
Signed-off-by: Roman Khimov <[email protected]>
@shargon please merge if others still not review, this proposal has being extensively discussed and reviewed and updated and apporoved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good it moved forward
This is a proposal for a new ABI standard replacing NEP-14. It solves the problem of opaque Array, Map and InteropInterface types allowing to provide more specific details about them. A somewhat similar thing is also provided in #151, but it's detached from the ABI and introduces some new notations that should be parsed by clients. This NEP is based on NeoGo ExtendedType data that is used for contract-specific RPC SDK generation, but that implementation is also detached from the ABI (an additional YAML file is used).
While this problem can be solved with additional (non-ABI) data, it might add some additional barriers affecting contract interoperability (starting with the basics, where to store this data). The intention here was to create a 100% backwards-compatible extension (if new fields are ignored) that can be easily provided by compilers and can be easily consumed by any other tools, irrespective of the implementation language. Having this data in ABI means every contract will have it and it'll be easily accessible. In fact this data is a part of the ABI in its essence, that's what contracts accept/return.
Things intentionally omitted for now (I'd like to get more feedback on this before doing any of those):
Any
parameter in the specification (likedata
fortransfer
in NEP-17 or NEP-11) with the contract using some specific type (if it usesdata
, it expects some particular type ofdata
)