diff --git a/README.mediawiki b/README.mediawiki index 2d7fe30f..57d8e6c4 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -45,12 +45,6 @@ First review [[nep-1.mediawiki|NEP-1]]. Then clone the repository and add your N | Standard | Final |- -| [[nep-14.mediawiki|14]] -| NeoContract ABI -| Erik Zhang -| Standard -| Final -|- | [[nep-15.mediawiki|15]] | NeoContract Manifest | Erik Zhang, Fernando Díaz Toledano, Vitor Nazário Coelho, Igor Machado Coelho, Li Jianying @@ -111,7 +105,12 @@ First review [[nep-1.mediawiki|NEP-1]]. Then clone the repository and add your N | Standard | Accepted |- -| +| [[nep-25.mediawiki|25]] +| NeoContract ABI +| Erik Zhang, Roman Khimov +| Standard +|- +| | Dynamic Sharding | | Standard diff --git a/nep-25.mediawiki b/nep-25.mediawiki new file mode 100644 index 00000000..6c986ebe --- /dev/null +++ b/nep-25.mediawiki @@ -0,0 +1,393 @@ +
+  NEP: 25
+  Title: NeoContract ABI
+  Author: Erik Zhang , Roman Khimov 
+  Type: Standard
+  Status: Accepted
+  Created: 2022-12-08
+  Replaces: 14
+
+ +==Abstract== + +An Application Binary Interface (ABI) is the interface between two program modules, one of which is often a library and/or operating system and the other one is usually an application created by a regular programmer. + +This NEP describes the ABI standards for Neo smart contracts. + +==Motivation== + +Neo smart contract system is designed to be mutually invocable between contracts. To achieve this, we need a mechanism for exposing the interface of smart contracts. With NeoContract ABI, developers can easily create programs to invoke smart contracts or write clients that automatically access contract functionalities. + +This NEP is a compatible extension of the previous one, +[https://github.com/neo-project/proposals/blob/06a6b550987a74025009cf6841757f2426462697/nep-14.mediawiki NEP-14]. Some complex +data types required more data for ABI to be useful for automatic SDK/wrapper +code generation. For example, parameter of "Array" type could be a structure +with three fields of "ByteArray", "Hash160" and "Integer" types or an array of +"Integer" values. These cases couldn't be differentiated both for method +parameters and return values with +[https://github.com/neo-project/proposals/blob/06a6b550987a74025009cf6841757f2426462697/nep-14.mediawiki NEP-14], while this proposal fixes it. + +==Rationale== + +We assume the ABI is strongly typed, known at compilation time and static. No introspection mechanism will be provided. We assert that all contracts will have the interface definitions of any contracts they call available at compile-time. + +This specification does not address contracts whose interface is dynamic or otherwise known only at run-time. Should these cases become important they can be adequately handled as facilities built within the Neo ecosystem. + +==Specification== + +Anywhere below "identifier" is an ASCII string that starts with a letter or underscore and contains letters, numbers or underscore. + +===Contract=== + +The NeoContract ABI is defined by JSON format, which has the following basic structure, where some of the top-level objects can have any number of child objects: + +
+{
+  "methods": [],
+  "events": [],
+  "namedtypes": {}
+}
+
+ +methods is an array of Method objects which describe the details of each method in the contract. + +events is an array of Event objects which describe the details of each event in the contract. + +namedtypes is an object with each member having a name (a string consisting of one or more identifiers joined by dots) and a value of ExtendedType object. + +===Method=== + +Method object has the following structure: + +
+{
+  "name": "transfer",
+  "offset": 0,
+  "safe": false,
+  "parameters": [],
+  "returntype": "Boolean",
+  "extendedreturntype": {}
+}
+
+ +name is the name of the method, which can be any valid identifier. + +offset is the offset of this method in the script. + +safe indicates if the method has any side-effects (storage changes or notifications), methods marked this way can only read contract state (usually returning something as a result), modification attempts will result in execution failure. + +parameters is an array of Parameter objects which describe the details of each parameter in the method. + +returntype indicates the return type of the method. It can have any value of the ParameterType enumeration defined below. + +extendedreturntype is an ExtendedType object used to provide additional type data if needed, this field can be omitted. + +===Event=== + +Event object has the following structure: + +
+{
+  "name": "refund",
+  "parameters": []
+}
+
+ +name is the name of the event, which can be any valid identifier. + +parameters is an array of Parameter objects which describe the details of each parameter in the event. + +===Parameter=== + +Parameter object has the following structure: + +
+{
+  "name": "from",
+  "type": "Hash160",
+  "extendedtype": {}
+}
+
+ +name is the name of the parameter, which can be any valid identifier. + +type indicates the type of the parameter. It can have any value of the ParameterType enumeration defined below, except for Void. + +extendedtype is an ExtendedType object used to provide additional type data if needed, this field can be omitted. + +===ParameterType=== + +ParameterType enum has the following values: + +{| +!name +!description +|- +| Signature +| A signature of a transaction or block which is generated by the user. +|- +| Boolean +| A boolean value can be either true or false. +|- +| Integer +| An arbitrarily large integer whose value in theory has no upper or lower bounds. +|- +| Hash160 +| A 160-bits integer. +|- +| Hash256 +| A 256-bits integer. +|- +| ByteArray +| A byte array. +|- +| PublicKey +| An ECC public key which is encoded with compressed mode. +|- +| String +| A string which is encoded in UTF-8. +|- +| Array +| An array of objects. The type of elements can be any value of ParameterType, unless some more specific type is specified with ExtendedType data. +|- +| Map +| A map of objects. The type of elements inside the key/value collection can be any value of ParameterType, unless some more specific types are specified with ExtendedType data. +|- +| InteropInterface +| An interface which is returned by interop services. More specific type can be specified with ExtendedType data. +|- +| Any +| Any means that the method will return a value of uncertain type. +|- +| Void +| Void means that the method has no return value. This value cannot be the type of a method parameter. +|} + +===ExtendedType=== + +Extended type data is an object can be used for extendedtype +and extendedreturntype fields or named types +(the object below is not a valid ExtendedType specification, rather it +represents all possible fields). + +
+{
+  "type": "Integer",
+  "namedtype": "name",
+  "length": 32,
+  "forbidnull": true,
+  "interface": "IIterator",
+  "key": "Integer",
+  "value": {},
+  "fields": []
+}
+
+ +type indicates the base type of the return value/parameter. +It can have any value of the ParameterType enumeration defined above. This +field is mandatory. When ExtendedType is used in extendedtype +this field MUST be the same as outer (Parameter's) type, when +used in extendedreturntype it MUST be the same as outer +(Method's) returntype, when used in one of namedtypes +it MUST be same as ExtendedType's type that refers to this +named type. + +namedtype is used to refer to one of the types defined in the +namedtypes object of Contract, so namedtypes MUST +contain a field named name . This field is only used for +structures (ordered set of named values of diffent types), if used other +fields MUST NOT be set, except for the type which MUST be an +Array. Value string MUST start with a letter and can contain +alphanumeric characters and dots. It MUST NOT be longer than 64 characters. + +length is an optional field that can be used for Integer, +ByteArray, String or Array types and +MUST NOT be used for other types. When used it specifies the maximum possible +byte length of an integer/byte array/string or number of array elements. +Any of these lengths MUST NOT exceed NeoVM limitations that are relevant for +the current version of it. Length 0 means "unlimited". + +forbidnull is an optional field that can be used for Hash160, +Hash256, ByteArray, String, Array, +Map or InteropInterface types and MUST NOT be used +for other types. It allows to specify that the method accepts or event emits +only non-null values for this field. The default (if not specified) is "false", +meaning that null can be used. + +interface is only used in conjuction with the +InteropInterface type and MUST NOT be used for other +types, when used it specifies which interop interface is used. The only valid +defined value for it is "IIterator" which means an iterator object. When used +it MUST be accompanied with the value object that specifies the +type of each individual element returned from the iterator. + +key is only used along with the Map +type (MUST NOT be used for other types) and can have +Signature, Boolean, Integer, +Hash160, Hash256, ByteArray, +PublicKey or String value, that is all the basic +types that can be used as a map key. + +value is used for Array, +InteropInterface and Map types (type +field) and MUST NOT be used with other base types. When used for +Array it contains the type of an individual element of an array +(ordered set of values of one type). If used for InteropInterface +it contains the type of an individual iterator's value. If used for +Map it contains map value type. If this field is used, +fields MUST NOT be present. + +fields is used for Array type and when +used it means that the type is a structure (ordered set of named values of +diffent types), which has its fields defined directly here (unlike +namedtype which is just a reference to +namedtypes). It's an array with each member being a +Parameter. fields MUST NOT be used in method parameter or return +value definitions (these MUST use namedtype referring to a valid +type specified in the namedtypes object). + +==Backwards Compatibility== + +For the field extension this NEP is completely backwards-compatible with +[https://github.com/neo-project/proposals/blob/06a6b550987a74025009cf6841757f2426462697/nep-14.mediawiki NEP-14] +when new fields are ignored, old fields and their meaning remain intact. + +This NEP has more strict requirements for identifiers, but these are mostly +clarifying what was meant implicitly earlier and practically it's compatible +with the old definition. + +==Test Cases== + +This is an example of the method definition that takes structure, array and +map parameters, returning an iterator with structured element type. + +
+{
+   "methods" : [
+      {
+         "returntype" : "InteropInterface",
+         "offset" : 0,
+         "safe" : true,
+         "extendedreturntype" : {
+            "value" : {
+               "type" : "Array",
+               "namedtype" : "package.Structure"
+            },
+            "type" : "InteropInterface",
+            "forbidnull" : true,
+            "interface" : "IIterator"
+         },
+         "name" : "m",
+         "parameters" : [
+            {
+               "name" : "structParam",
+               "type" : "Array",
+               "extendedtype" : {
+                  "type" : "Array",
+                  "namedtype" : "local.Structure"
+               }
+            },
+            {
+               "extendedtype" : {
+                  "value" : {
+                     "type" : "Hash160"
+                  },
+                  "type" : "Array"
+               },
+               "name" : "arrayOfHash160",
+               "type" : "Array"
+            },
+            {
+               "name" : "mapParam",
+               "type" : "Map",
+               "extendedtype" : {
+                  "value" : {
+                     "type" : "Integer"
+                  },
+                  "type" : "Map",
+                  "key" : "Hash160"
+               }
+            }
+         ]
+      }
+   ],
+   "events" : [],
+   "namedtypes" : {
+      "local.Structure" : {
+         "fields" : [
+            {
+               "name" : "IntField",
+               "type" : "Integer"
+            },
+            {
+               "name" : "Hash256Field",
+               "type" : "Hash256"
+            },
+            {
+               "name" : "ArrayOfArraysOfBooleans",
+               "type" : "Array",
+               "extendedtype" : {
+                  "type" : "Array",
+                  "value" : {
+                     "extendedtype" : {
+                        "value" : {
+                           "type" : "Boolean"
+                        },
+                        "type" : "Array"
+                     },
+                     "type" : "Array"
+                  }
+               }
+            },
+            {
+               "name" : "StructureField",
+               "type" : "Array",
+               "extendedtype" : {
+                  "type" : "Array",
+                  "namedtype" : "package.Structure"
+               }
+            }
+         ],
+         "type" : "Array"
+      },
+      "package.Structure" : {
+         "type" : "Array",
+         "fields" : [
+            {
+               "name" : "MapHash160ToArrayOfIntegers",
+               "type" : "Map",
+               "extendedtype" : {
+                  "type" : "Map",
+                  "key" : "Hash160",
+                  "value" : {
+                     "extendedtype" : {
+                        "value" : {
+                           "type" : "Integer"
+                        },
+                        "type" : "Array"
+                     },
+                     "type" : "Array"
+                  }
+               }
+            },
+            {
+               "name" : "Int32Field",
+               "type" : "Integer",
+               "extendedtype" : {
+                  "type" : "Integer",
+                  "length" : 4
+               }
+            },
+            {
+               "name" : "StringField",
+               "type" : "String"
+            },
+            {
+               "name" : "ByteArrayField",
+               "type" : "ByteArray"
+            }
+         ]
+      }
+   }
+}
+
diff --git a/nep-14.mediawiki b/obsolete/nep-14.mediawiki similarity index 99% rename from nep-14.mediawiki rename to obsolete/nep-14.mediawiki index fce99ff8..6149b085 100644 --- a/nep-14.mediawiki +++ b/obsolete/nep-14.mediawiki @@ -3,7 +3,7 @@ Title: NeoContract ABI Author: Erik Zhang Type: Standard - Status: Final + Status: Obsolete Created: 2020-03-25 Replaces: 3