diff --git a/.gitignore b/.gitignore index bbde7b23..c01983fa 100644 --- a/.gitignore +++ b/.gitignore @@ -77,6 +77,7 @@ secring.* ### Custom items .idea +**/*.iml *.sw* *.iml diff --git a/README.md b/README.md index f608afd1..de62f09e 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,10 @@ from the _*.proto_ files in the following repositories: ## Overview of services There are five primary service families, which inter-operate on entities -controlled by one (or more) Ed25519 keypairs: +controlled by one (or more) Ed25519 or ECDSA(secp256k1) keypairs: 1. The [cryptocurrency service](services/crypto_service.proto), for cryptocurrency accounts with transfers denominated -in [hBar (ℏ)](https://help.hedera.com/hc/en-us/articles/360000674317-What-are-the-official-HBAR-cryptocurrency-denominations-). +in [hbar (ℏ)](https://help.hedera.com/hc/en-us/articles/360000674317-What-are-the-official-HBAR-cryptocurrency-denominations-). 2. The [consensus service](services/consensus_service.proto), for fast and unbiased ordering of opaque binary messages exchanged on arbitrary topics. @@ -38,7 +38,7 @@ privileged accounts to suspend network operations during a maintenance window. It is important to note that most network services are gated by fees which must be paid in ℏ from a cryptocurrency account. The payer authorizes a fee by signing an appropriate transaction with a sufficient subset of the -Ed25519 key(s) associated to their account. +cryptographic key(s) associated to their account. ## Overview of state State directory and its subdirectories contain the protobuf files that define the state of the network. @@ -51,11 +51,9 @@ The state directory and its subdirectories are in preview and are subject to ch # For Developers ## Branching -This repository uses a simple branching model with only two distinguished branches: - 1. The head of `main` points to the latest protobufs blessed for deployment to mainnet. +This repository uses a simple branching model with only one distinguished branch; +`main` points to the latest protobufs intended for the next deployment to mainnet. Tags such as `v0.12.0` mark commits used for testnet and mainnet deploys. - 2. The head of `develop` points to the latest candidate for the next tag in `main`. -Tags suffixed with `-alpha.x` mark commits used for previewnet deploys. ## PBJ Package Support Proto files in this repo are generated into two kinds of Java files, one using **protoc** and other using @@ -65,4 +63,4 @@ need to have an option of the form: // <<>> This comment is special code for setting PBJ Compiler java package ``` To specify the Java package for PBJ generated model objects. This option is ignored by **protoc**. PBJ ignores the default -option `option java_package = "com.hederahashgraph.api.proto.java";` which is used by **protoc** to generate Java files. \ No newline at end of file +option `option java_package = "com.hederahashgraph.api.proto.java";` which is used by **protoc** to generate Java files. diff --git a/block/block_service.proto b/block/block_service.proto index d780c6d5..7689514c 100644 --- a/block/block_service.proto +++ b/block/block_service.proto @@ -19,17 +19,19 @@ * >> due to issue 262 * > * > Issue 240 - * >> These files currently cause PBJ integration tests to fail if included - * >> due to issue 240. + * >> These files may cause PBJ integration tests to fail if included + * >> due to issue 240. This was worked around by specifying different + * >> values for java_package and pbj.java_package. * > * > Issue 218 - * >> These files have the same value for package and java_package. Ideally - * >> we would not specify `java_package` or the pbj comment in that situation, - * >> but Issue 218 prevents eliding the unnecessary directives. + * >> These files _should_ have the same value for package and java_package. + * >> Ideally we would not specify `java_package` or the pbj comment in that + * >> situation, but Issue 218 prevents eliding the unnecessary directives. * > * > Issue 217 * >> These files may cause PBJ to fail compilation due to comments preceeding - * >> the `syntax` keyword. + * >> the `syntax` keyword. Currently this is a warning, but in projects that + * >> make warnings errors, this will cause compilation to fail. * > * > Issue 216 * >> These files would do well with validation support, but cannot make @@ -790,9 +792,9 @@ message BlockNodeVersions { } /** - * Remote procedure calls (RPCs) for the Block Node. + * Remote procedure calls (RPCs) for the Block Node ancillary services. */ -service BlockStreamService { +service BlockNodeService { /** * Read the status of this block node server. *

@@ -800,14 +802,25 @@ service BlockStreamService { * data or a state snapshot. */ rpc serverStatus(ServerStatusRequest) returns (ServerStatusResponse); +} +/** + * Remote procedure calls (RPCs) for the Block Node block services. + */ +service BlockAccessService { /** * Read a single block from the block node. *

* The request SHALL describe the block number of the block to retrieve. */ rpc singleBlock(SingleBlockRequest) returns (SingleBlockResponse); +} +/** + * Remote procedure calls (RPCs) for the Block Node state snapshot + * and query services. + */ +service StateService { /** * Read a state snapshot from the block node. *

@@ -818,6 +831,12 @@ service BlockStreamService { */ rpc stateSnapshot(StateSnapshotRequest) returns (StateSnapshotResponse); +} + +/** + * Remote procedure calls (RPCs) for the Block Node stream services. + */ +service BlockStreamService { /** * Publish a stream of blocks. *

diff --git a/block/stream/output/consensus_service.proto b/block/stream/output/consensus_service.proto index 436ad37a..f9f3bab5 100644 --- a/block/stream/output/consensus_service.proto +++ b/block/stream/output/consensus_service.proto @@ -6,7 +6,11 @@ * ### Topic Running Hash Calculation * Submitted messages include a topic running hash. This value has changed * over time, with the known versions detailed in the `RunningHashVersion` - * enumeration. + * enumeration. The running hash version SHALL NOT be transmitted in the + * Block Stream, however, as it is a fixed value that can only be changed + * with a new release of consensus node software following a HIP to update + * the specification, so repeating that fixed value in the block stream is + * wasteful and unnecessary. * * ### Keywords * The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", diff --git a/block/stream/output/smart_contract_service.proto b/block/stream/output/smart_contract_service.proto index 81062c26..3e3e195d 100644 --- a/block/stream/output/smart_contract_service.proto +++ b/block/stream/output/smart_contract_service.proto @@ -40,7 +40,7 @@ option java_package = "com.hedera.hapi.block.stream.output.protoc"; // <<>> This comment is special code for setting PBJ Compiler java package option java_multiple_files = true; -import "contract_call_local.proto"; +import "contract_types.proto"; import "sidecar_file.proto"; /** diff --git a/block/stream/output/state_changes.proto b/block/stream/output/state_changes.proto index f3284fdb..2aca288a 100644 --- a/block/stream/output/state_changes.proto +++ b/block/stream/output/state_changes.proto @@ -57,6 +57,7 @@ import "state/token/account.proto"; import "state/token/account_pending_airdrop.proto"; import "state/token/network_staking_rewards.proto"; import "state/token/nft.proto"; +import "state/platform_state.proto"; import "state/token/staking_node_info.proto"; import "state/token/token.proto"; import "state/token/token_relation.proto"; diff --git a/buf/validate/expression.proto b/buf/validate/expression.proto new file mode 100644 index 00000000..72ce36dc --- /dev/null +++ b/buf/validate/expression.proto @@ -0,0 +1,92 @@ +// Copyright 2023 Buf Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package buf.validate; + +option go_package = "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate"; +option java_multiple_files = true; +option java_outer_classname = "ExpressionProto"; +option java_package = "build.buf.validate"; + +// `Constraint` represents a validation rule written in the Common Expression +// Language (CEL) syntax. Each Constraint includes a unique identifier, an +// optional error message, and the CEL expression to evaluate. For more +// information on CEL, [see our documentation](https://github.com/bufbuild/protovalidate/blob/main/docs/cel.md). +// +// ```proto +// message Foo { +// option (buf.validate.message).cel = { +// id: "foo.bar" +// message: "bar must be greater than 0" +// expression: "this.bar > 0" +// }; +// int32 bar = 1; +// } +// ``` +message Constraint { + // `id` is a string that serves as a machine-readable name for this Constraint. + // It should be unique within its scope, which could be either a message or a field. + string id = 1; + + // `message` is an optional field that provides a human-readable error message + // for this Constraint when the CEL expression evaluates to false. If a + // non-empty message is provided, any strings resulting from the CEL + // expression evaluation are ignored. + string message = 2; + + // `expression` is the actual CEL expression that will be evaluated for + // validation. This string must resolve to either a boolean or a string + // value. If the expression evaluates to false or a non-empty string, the + // validation is considered failed, and the message is rejected. + string expression = 3; +} + +// `Violations` is a collection of `Violation` messages. This message type is returned by +// protovalidate when a proto message fails to meet the requirements set by the `Constraint` validation rules. +// Each individual violation is represented by a `Violation` message. +message Violations { + // `violations` is a repeated field that contains all the `Violation` messages corresponding to the violations detected. + repeated Violation violations = 1; +} + +// `Violation` represents a single instance where a validation rule, expressed +// as a `Constraint`, was not met. It provides information about the field that +// caused the violation, the specific constraint that wasn't fulfilled, and a +// human-readable error message. +// +// ```json +// { +// "fieldPath": "bar", +// "constraintId": "foo.bar", +// "message": "bar must be greater than 0" +// } +// ``` +message Violation { + // `field_path` is a machine-readable identifier that points to the specific field that failed the validation. + // This could be a nested field, in which case the path will include all the parent fields leading to the actual field that caused the violation. + string field_path = 1; + + // `constraint_id` is the unique identifier of the `Constraint` that was not fulfilled. + // This is the same `id` that was specified in the `Constraint` message, allowing easy tracing of which rule was violated. + string constraint_id = 2; + + // `message` is a human-readable error message that describes the nature of the violation. + // This can be the default error message from the violated `Constraint`, or it can be a custom message that gives more context about the violation. + string message = 3; + + // `for_key` indicates whether the violation was caused by a map key, rather than a value. + bool for_key = 4; +} diff --git a/buf/validate/priv/private.proto b/buf/validate/priv/private.proto new file mode 100644 index 00000000..ddaf938a --- /dev/null +++ b/buf/validate/priv/private.proto @@ -0,0 +1,41 @@ +// Copyright 2023 Buf Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package buf.validate.priv; + +import "google/protobuf/descriptor.proto"; + +option go_package = "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate/priv"; +option java_multiple_files = true; +option java_outer_classname = "PrivateProto"; +option java_package = "build.buf.validate.priv"; + +extend google.protobuf.FieldOptions { + // Do not use. Internal to protovalidate library + optional FieldConstraints field = 1160; +} + +// Do not use. Internal to protovalidate library +message FieldConstraints { + repeated Constraint cel = 1; +} + +// Do not use. Internal to protovalidate library +message Constraint { + string id = 1; + string message = 2; + string expression = 3; +} diff --git a/buf/validate/validate.proto b/buf/validate/validate.proto new file mode 100644 index 00000000..09fa744b --- /dev/null +++ b/buf/validate/validate.proto @@ -0,0 +1,4106 @@ +// Copyright 2023 Buf Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package buf.validate; + +import "buf/validate/expression.proto"; +import "buf/validate/priv/private.proto"; +import "google/protobuf/descriptor.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate"; +option java_multiple_files = true; +option java_outer_classname = "ValidateProto"; +option java_package = "build.buf.validate"; + +// MessageOptions is an extension to google.protobuf.MessageOptions. It allows +// the addition of validation rules at the message level. These rules can be +// applied to incoming messages to ensure they meet certain criteria before +// being processed. +extend google.protobuf.MessageOptions { + // Rules specify the validations to be performed on this message. By default, + // no validation is performed against a message. + optional MessageConstraints message = 1159; +} + +// OneofOptions is an extension to google.protobuf.OneofOptions. It allows +// the addition of validation rules on a oneof. These rules can be +// applied to incoming messages to ensure they meet certain criteria before +// being processed. +extend google.protobuf.OneofOptions { + // Rules specify the validations to be performed on this oneof. By default, + // no validation is performed against a oneof. + optional OneofConstraints oneof = 1159; +} + +// FieldOptions is an extension to google.protobuf.FieldOptions. It allows +// the addition of validation rules at the field level. These rules can be +// applied to incoming messages to ensure they meet certain criteria before +// being processed. +extend google.protobuf.FieldOptions { + // Rules specify the validations to be performed on this field. By default, + // no validation is performed against a field. + optional FieldConstraints field = 1159; +} + +// MessageConstraints represents validation rules that are applied to the entire message. +// It includes disabling options and a list of Constraint messages representing Common Expression Language (CEL) validation rules. +message MessageConstraints { + // `disabled` is a boolean flag that, when set to true, nullifies any validation rules for this message. + // This includes any fields within the message that would otherwise support validation. + // + // ```proto + // message MyMessage { + // // validation will be bypassed for this message + // option (buf.validate.message).disabled = true; + // } + // ``` + optional bool disabled = 1; + + // `cel` is a repeated field of type Constraint. Each Constraint specifies a validation rule to be applied to this message. + // These constraints are written in Common Expression Language (CEL) syntax. For more information on + // CEL, [see our documentation](https://github.com/bufbuild/protovalidate/blob/main/docs/cel.md). + // + // + // ```proto + // message MyMessage { + // // The field `foo` must be greater than 42. + // option (buf.validate.message).cel = { + // id: "my_message.value", + // message: "value must be greater than 42", + // expression: "this.foo > 42", + // }; + // optional int32 foo = 1; + // } + // ``` + repeated Constraint cel = 3; +} + +// The `OneofConstraints` message type enables you to manage constraints for +// oneof fields in your protobuf messages. +message OneofConstraints { + // If `required` is true, exactly one field of the oneof must be present. A + // validation error is returned if no fields in the oneof are present. The + // field itself may still be a default value; further constraints + // should be placed on the fields themselves to ensure they are valid values, + // such as `min_len` or `gt`. + // + // ```proto + // message MyMessage { + // oneof value { + // // Either `a` or `b` must be set. If `a` is set, it must also be + // // non-empty; whereas if `b` is set, it can still be an empty string. + // option (buf.validate.oneof).required = true; + // string a = 1 [(buf.validate.field).string.min_len = 1]; + // string b = 2; + // } + // } + // ``` + optional bool required = 1; +} + +// FieldRules encapsulates the rules for each type of field. Depending on the +// field, the correct set should be used to ensure proper validations. +message FieldConstraints { + // `cel` is a repeated field used to represent a textual expression + // in the Common Expression Language (CEL) syntax. For more information on + // CEL, [see our documentation](https://github.com/bufbuild/protovalidate/blob/main/docs/cel.md). + // + // ```proto + // message MyMessage { + // // The field `value` must be greater than 42. + // optional int32 value = 1 [(buf.validate.field).cel = { + // id: "my_message.value", + // message: "value must be greater than 42", + // expression: "this > 42", + // }]; + // } + // ``` + repeated Constraint cel = 23; + // If `required` is true, the field must be populated. A populated field can be + // described as "serialized in the wire format," which includes: + // + // - the following "nullable" fields must be explicitly set to be considered populated: + // - singular message fields (whose fields may be unpopulated/default values) + // - member fields of a oneof (may be their default value) + // - proto3 optional fields (may be their default value) + // - proto2 scalar fields (both optional and required) + // - proto3 scalar fields must be non-zero to be considered populated + // - repeated and map fields must be non-empty to be considered populated + // + // ```proto + // message MyMessage { + // // The field `value` must be set to a non-null value. + // optional MyOtherMessage value = 1 [(buf.validate.field).required = true]; + // } + // ``` + bool required = 25; + // Skip validation on the field if its value matches the specified criteria. + // See Ignore enum for details. + // + // ```proto + // message UpdateRequest { + // // The uri rule only applies if the field is populated and not an empty + // // string. + // optional string url = 1 [ + // (buf.validate.field).ignore = IGNORE_IF_DEFAULT_VALUE, + // (buf.validate.field).string.uri = true, + // ]; + // } + // ``` + Ignore ignore = 27; + + oneof type { + // Scalar Field Types + FloatRules float = 1; + DoubleRules double = 2; + Int32Rules int32 = 3; + Int64Rules int64 = 4; + UInt32Rules uint32 = 5; + UInt64Rules uint64 = 6; + SInt32Rules sint32 = 7; + SInt64Rules sint64 = 8; + Fixed32Rules fixed32 = 9; + Fixed64Rules fixed64 = 10; + SFixed32Rules sfixed32 = 11; + SFixed64Rules sfixed64 = 12; + BoolRules bool = 13; + StringRules string = 14; + BytesRules bytes = 15; + + // Complex Field Types + EnumRules enum = 16; + RepeatedRules repeated = 18; + MapRules map = 19; + + // Well-Known Field Types + AnyRules any = 20; + DurationRules duration = 21; + TimestampRules timestamp = 22; + } + + // DEPRECATED: use ignore=IGNORE_ALWAYS instead. TODO: remove this field pre-v1. + bool skipped = 24 [deprecated = true]; + // DEPRECATED: use ignore=IGNORE_IF_UNPOPULATED instead. TODO: remove this field pre-v1. + bool ignore_empty = 26 [deprecated = true]; +} + +// Specifies how FieldConstraints.ignore behaves. See the documentation for +// FieldConstraints.required for definitions of "populated" and "nullable". +enum Ignore { + // buf:lint:ignore ENUM_NO_ALLOW_ALIAS // allowance for deprecations. TODO: remove pre-v1. + option allow_alias = true; + // Validation is only skipped if it's an unpopulated nullable fields. + // + // ```proto + // syntax="proto3"; + // + // message Request { + // // The uri rule applies to any value, including the empty string. + // string foo = 1 [ + // (buf.validate.field).string.uri = true + // ]; + // + // // The uri rule only applies if the field is set, including if it's + // // set to the empty string. + // optional string bar = 2 [ + // (buf.validate.field).string.uri = true + // ]; + // + // // The min_items rule always applies, even if the list is empty. + // repeated string baz = 3 [ + // (buf.validate.field).repeated.min_items = 3 + // ]; + // + // // The custom CEL rule applies only if the field is set, including if + // // it's the "zero" value of that message. + // SomeMessage quux = 4 [ + // (buf.validate.field).cel = {/* ... */} + // ]; + // } + // ``` + IGNORE_UNSPECIFIED = 0; + + // Validation is skipped if the field is unpopulated. This rule is redundant + // if the field is already nullable. This value is equivalent behavior to the + // deprecated ignore_empty rule. + // + // ```proto + // syntax="proto3 + // + // message Request { + // // The uri rule applies only if the value is not the empty string. + // string foo = 1 [ + // (buf.validate.field).string.uri = true, + // (buf.validate.field).ignore = IGNORE_IF_UNPOPULATED + // ]; + // + // // IGNORE_IF_UNPOPULATED is equivalent to IGNORE_UNSPECIFIED in this + // // case: the uri rule only applies if the field is set, including if + // // it's set to the empty string. + // optional string bar = 2 [ + // (buf.validate.field).string.uri = true, + // (buf.validate.field).ignore = IGNORE_IF_UNPOPULATED + // ]; + // + // // The min_items rule only applies if the list has at least one item. + // repeated string baz = 3 [ + // (buf.validate.field).repeated.min_items = 3, + // (buf.validate.field).ignore = IGNORE_IF_UNPOPULATED + // ]; + // + // // IGNORE_IF_UNPOPULATED is equivalent to IGNORE_UNSPECIFIED in this + // // case: the custom CEL rule applies only if the field is set, including + // // if it's the "zero" value of that message. + // SomeMessage quux = 4 [ + // (buf.validate.field).cel = {/* ... */}, + // (buf.validate.field).ignore = IGNORE_IF_UNPOPULATED + // ]; + // } + // ``` + IGNORE_IF_UNPOPULATED = 1; + + // Validation is skipped if the field is unpopulated or if it is a nullable + // field populated with its default value. This is typically the zero or + // empty value, but proto2 scalars support custom defaults. For messages, the + // default is a non-null message with all its fields unpopulated. + // + // ```proto + // syntax="proto3 + // + // message Request { + // // IGNORE_IF_DEFAULT_VALUE is equivalent to IGNORE_IF_UNPOPULATED in + // // this case; the uri rule applies only if the value is not the empty + // // string. + // string foo = 1 [ + // (buf.validate.field).string.uri = true, + // (buf.validate.field).ignore = IGNORE_IF_DEFAULT_VALUE + // ]; + // + // // The uri rule only applies if the field is set to a value other than + // // the empty string. + // optional string bar = 2 [ + // (buf.validate.field).string.uri = true, + // (buf.validate.field).ignore = IGNORE_IF_DEFAULT_VALUE + // ]; + // + // // IGNORE_IF_DEFAULT_VALUE is equivalent to IGNORE_IF_UNPOPULATED in + // // this case; the min_items rule only applies if the list has at least + // // one item. + // repeated string baz = 3 [ + // (buf.validate.field).repeated.min_items = 3, + // (buf.validate.field).ignore = IGNORE_IF_DEFAULT_VALUE + // ]; + // + // // The custom CEL rule only applies if the field is set to a value other + // // than an empty message (i.e., fields are unpopulated). + // SomeMessage quux = 4 [ + // (buf.validate.field).cel = {/* ... */}, + // (buf.validate.field).ignore = IGNORE_IF_DEFAULT_VALUE + // ]; + // } + // ``` + // + // This rule is affected by proto2 custom default values: + // + // ```proto + // syntax="proto2"; + // + // message Request { + // // The gt rule only applies if the field is set and it's value is not + // the default (i.e., not -42). The rule even applies if the field is set + // to zero since the default value differs. + // optional int32 value = 1 [ + // default = -42, + // (buf.validate.field).int32.gt = 0, + // (buf.validate.field).ignore = IGNORE_IF_DEFAULT_VALUE + // ]; + // } + IGNORE_IF_DEFAULT_VALUE = 2; + + // The validation rules of this field will be skipped and not evaluated. This + // is useful for situations that necessitate turning off the rules of a field + // containing a message that may not make sense in the current context, or to + // temporarily disable constraints during development. + // + // ```proto + // message MyMessage { + // // The field's rules will always be ignored, including any validation's + // // on value's fields. + // MyOtherMessage value = 1 [ + // (buf.validate.field).ignore = IGNORE_ALWAYS]; + // } + // ``` + IGNORE_ALWAYS = 3; + + // Deprecated: Use IGNORE_IF_UNPOPULATED instead. TODO: Remove this value pre-v1. + IGNORE_EMPTY = 1 [deprecated = true]; + // Deprecated: Use IGNORE_IF_DEFAULT_VALUE. TODO: Remove this value pre-v1. + IGNORE_DEFAULT = 2 [deprecated = true]; +} + +// FloatRules describes the constraints applied to `float` values. These +// rules may also be applied to the `google.protobuf.FloatValue` Well-Known-Type. +message FloatRules { + // `const` requires the field value to exactly match the specified value. If + // the field value doesn't match, an error message is generated. + // + // ```proto + // message MyFloat { + // // value must equal 42.0 + // float value = 1 [(buf.validate.field).float.const = 42.0]; + // } + // ``` + optional float const = 1 [(priv.field).cel = { + id: "float.const", + expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''", + }]; + + oneof less_than { + // `lt` requires the field value to be less than the specified value (field < + // value). If the field value is equal to or greater than the specified value, + // an error message is generated. + // + // ```proto + // message MyFloat { + // // value must be less than 10.0 + // float value = 1 [(buf.validate.field).float.lt = 10.0]; + // } + // ``` + float lt = 2 [(priv.field).cel = { + id: "float.lt", + expression: + "!has(rules.gte) && !has(rules.gt) && (this.isNan() || this >= rules.lt)" + "? 'value must be less than %s'.format([rules.lt]) : ''" + }]; + + // `lte` requires the field value to be less than or equal to the specified + // value (field <= value). If the field value is greater than the specified + // value, an error message is generated. + // + // ```proto + // message MyFloat { + // // value must be less than or equal to 10.0 + // float value = 1 [(buf.validate.field).float.lte = 10.0]; + // } + // ``` + float lte = 3 [(priv.field).cel = { + id: "float.lte", + expression: + "!has(rules.gte) && !has(rules.gt) && (this.isNan() || this > rules.lte)" + "? 'value must be less than or equal to %s'.format([rules.lte]) : ''" + }]; + } + + oneof greater_than { + // `gt` requires the field value to be greater than the specified value + // (exclusive). If the value of `gt` is larger than a specified `lt` or + // `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MyFloat { + // // value must be greater than 5.0 [float.gt] + // float value = 1 [(buf.validate.field).float.gt = 5.0]; + // + // // value must be greater than 5 and less than 10.0 [float.gt_lt] + // float other_value = 2 [(buf.validate.field).float = { gt: 5.0, lt: 10.0 }]; + // + // // value must be greater than 10 or less than 5.0 [float.gt_lt_exclusive] + // float another_value = 3 [(buf.validate.field).float = { gt: 10.0, lt: 5.0 }]; + // } + // ``` + float gt = 4 [ + (priv.field).cel = { + id: "float.gt", + expression: + "!has(rules.lt) && !has(rules.lte) && (this.isNan() || this <= rules.gt)" + "? 'value must be greater than %s'.format([rules.gt]) : ''" + }, + (priv.field).cel = { + id: "float.gt_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gt && (this.isNan() || this >= rules.lt || this <= rules.gt)" + "? 'value must be greater than %s and less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "float.gt_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gt && (this.isNan() || (rules.lt <= this && this <= rules.gt))" + "? 'value must be greater than %s or less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "float.gt_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gt && (this.isNan() || this > rules.lte || this <= rules.gt)" + "? 'value must be greater than %s and less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "float.gt_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gt && (this.isNan() || (rules.lte < this && this <= rules.gt))" + "? 'value must be greater than %s or less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + } + ]; + + // `gte` requires the field value to be greater than or equal to the specified + // value (exclusive). If the value of `gte` is larger than a specified `lt` + // or `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MyFloat { + // // value must be greater than or equal to 5.0 [float.gte] + // float value = 1 [(buf.validate.field).float.gte = 5.0]; + // + // // value must be greater than or equal to 5.0 and less than 10.0 [float.gte_lt] + // float other_value = 2 [(buf.validate.field).float = { gte: 5.0, lt: 10.0 }]; + // + // // value must be greater than or equal to 10.0 or less than 5.0 [float.gte_lt_exclusive] + // float another_value = 3 [(buf.validate.field).float = { gte: 10.0, lt: 5.0 }]; + // } + // ``` + float gte = 5 [ + (priv.field).cel = { + id: "float.gte", + expression: + "!has(rules.lt) && !has(rules.lte) && (this.isNan() || this < rules.gte)" + "? 'value must be greater than or equal to %s'.format([rules.gte]) : ''" + }, + (priv.field).cel = { + id: "float.gte_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gte && (this.isNan() || this >= rules.lt || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "float.gte_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gte && (this.isNan() || (rules.lt <= this && this < rules.gte))" + "? 'value must be greater than or equal to %s or less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "float.gte_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gte && (this.isNan() || this > rules.lte || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "float.gte_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gte && (this.isNan() || (rules.lte < this && this < rules.gte))" + "? 'value must be greater than or equal to %s or less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + } + ]; + } + + // `in` requires the field value to be equal to one of the specified values. + // If the field value isn't one of the specified values, an error message + // is generated. + // + // ```proto + // message MyFloat { + // // value must be in list [1.0, 2.0, 3.0] + // repeated float value = 1 (buf.validate.field).float = { in: [1.0, 2.0, 3.0] }; + // } + // ``` + repeated float in = 6 [(priv.field).cel = { + id: "float.in", + expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''", + }]; + + // `in` requires the field value to not be equal to any of the specified + // values. If the field value is one of the specified values, an error + // message is generated. + // + // ```proto + // message MyFloat { + // // value must not be in list [1.0, 2.0, 3.0] + // repeated float value = 1 (buf.validate.field).float = { not_in: [1.0, 2.0, 3.0] }; + // } + // ``` + repeated float not_in = 7 [(priv.field).cel = { + id: "float.not_in", + expression: "this in rules.not_in ? 'value must not be in list %s'.format([rules.not_in]) : ''", + }]; + + // `finite` requires the field value to be finite. If the field value is + // infinite or NaN, an error message is generated. + bool finite = 8 [(priv.field).cel = { + id: "float.finite", + expression: "this.isNan() || this.isInf() ? 'value must be finite' : ''", + }]; +} + +// DoubleRules describes the constraints applied to `double` values. These +// rules may also be applied to the `google.protobuf.DoubleValue` Well-Known-Type. +message DoubleRules { + // `const` requires the field value to exactly match the specified value. If + // the field value doesn't match, an error message is generated. + // + // ```proto + // message MyDouble { + // // value must equal 42.0 + // double value = 1 [(buf.validate.field).double.const = 42.0]; + // } + // ``` + optional double const = 1 [(priv.field).cel = { + id: "double.const", + expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''", + }]; + oneof less_than { + // `lt` requires the field value to be less than the specified value (field < + // value). If the field value is equal to or greater than the specified + // value, an error message is generated. + // + // ```proto + // message MyDouble { + // // value must be less than 10.0 + // double value = 1 [(buf.validate.field).double.lt = 10.0]; + // } + // ``` + double lt = 2 [(priv.field).cel = { + id: "double.lt", + expression: + "!has(rules.gte) && !has(rules.gt) && (this.isNan() || this >= rules.lt)" + "? 'value must be less than %s'.format([rules.lt]) : ''" + }]; + + // `lte` requires the field value to be less than or equal to the specified value + // (field <= value). If the field value is greater than the specified value, + // an error message is generated. + // + // ```proto + // message MyDouble { + // // value must be less than or equal to 10.0 + // double value = 1 [(buf.validate.field).double.lte = 10.0]; + // } + // ``` + double lte = 3 [(priv.field).cel = { + id: "double.lte", + expression: + "!has(rules.gte) && !has(rules.gt) && (this.isNan() || this > rules.lte)" + "? 'value must be less than or equal to %s'.format([rules.lte]) : ''" + }]; + } + oneof greater_than { + // `gt` requires the field value to be greater than the specified value + // (exclusive). If the value of `gt` is larger than a specified `lt` or `lte`, + // the range is reversed, and the field value must be outside the specified + // range. If the field value doesn't meet the required conditions, an error + // message is generated. + // + // ```proto + // message MyDouble { + // // value must be greater than 5.0 [double.gt] + // double value = 1 [(buf.validate.field).double.gt = 5.0]; + // + // // value must be greater than 5 and less than 10.0 [double.gt_lt] + // double other_value = 2 [(buf.validate.field).double = { gt: 5.0, lt: 10.0 }]; + // + // // value must be greater than 10 or less than 5.0 [double.gt_lt_exclusive] + // double another_value = 3 [(buf.validate.field).double = { gt: 10.0, lt: 5.0 }]; + // } + // ``` + double gt = 4 [ + (priv.field).cel = { + id: "double.gt", + expression: + "!has(rules.lt) && !has(rules.lte) && (this.isNan() || this <= rules.gt)" + "? 'value must be greater than %s'.format([rules.gt]) : ''" + }, + (priv.field).cel = { + id: "double.gt_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gt && (this.isNan() || this >= rules.lt || this <= rules.gt)" + "? 'value must be greater than %s and less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "double.gt_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gt && (this.isNan() || (rules.lt <= this && this <= rules.gt))" + "? 'value must be greater than %s or less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "double.gt_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gt && (this.isNan() || this > rules.lte || this <= rules.gt)" + "? 'value must be greater than %s and less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "double.gt_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gt && (this.isNan() || (rules.lte < this && this <= rules.gt))" + "? 'value must be greater than %s or less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + } + ]; + + // `gte` requires the field value to be greater than or equal to the specified + // value (exclusive). If the value of `gte` is larger than a specified `lt` or + // `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MyDouble { + // // value must be greater than or equal to 5.0 [double.gte] + // double value = 1 [(buf.validate.field).double.gte = 5.0]; + // + // // value must be greater than or equal to 5.0 and less than 10.0 [double.gte_lt] + // double other_value = 2 [(buf.validate.field).double = { gte: 5.0, lt: 10.0 }]; + // + // // value must be greater than or equal to 10.0 or less than 5.0 [double.gte_lt_exclusive] + // double another_value = 3 [(buf.validate.field).double = { gte: 10.0, lt: 5.0 }]; + // } + // ``` + double gte = 5 [ + (priv.field).cel = { + id: "double.gte", + expression: + "!has(rules.lt) && !has(rules.lte) && (this.isNan() || this < rules.gte)" + "? 'value must be greater than or equal to %s'.format([rules.gte]) : ''" + }, + (priv.field).cel = { + id: "double.gte_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gte && (this.isNan() || this >= rules.lt || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "double.gte_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gte && (this.isNan() || (rules.lt <= this && this < rules.gte))" + "? 'value must be greater than or equal to %s or less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "double.gte_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gte && (this.isNan() || this > rules.lte || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "double.gte_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gte && (this.isNan() || (rules.lte < this && this < rules.gte))" + "? 'value must be greater than or equal to %s or less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + } + ]; + } + // `in` requires the field value to be equal to one of the specified values. + // If the field value isn't one of the specified values, an error message is + // generated. + // + // ```proto + // message MyDouble { + // // value must be in list [1.0, 2.0, 3.0] + // repeated double value = 1 (buf.validate.field).double = { in: [1.0, 2.0, 3.0] }; + // } + // ``` + repeated double in = 6 [(priv.field).cel = { + id: "double.in", + expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''", + }]; + + // `not_in` requires the field value to not be equal to any of the specified + // values. If the field value is one of the specified values, an error + // message is generated. + // + // ```proto + // message MyDouble { + // // value must not be in list [1.0, 2.0, 3.0] + // repeated double value = 1 (buf.validate.field).double = { not_in: [1.0, 2.0, 3.0] }; + // } + // ``` + repeated double not_in = 7 [(priv.field).cel = { + id: "double.not_in", + expression: "this in rules.not_in ? 'value must not be in list %s'.format([rules.not_in]) : ''", + }]; + + // `finite` requires the field value to be finite. If the field value is + // infinite or NaN, an error message is generated. + bool finite = 8 [(priv.field).cel = { + id: "double.finite", + expression: "this.isNan() || this.isInf() ? 'value must be finite' : ''", + }]; +} + +// Int32Rules describes the constraints applied to `int32` values. These +// rules may also be applied to the `google.protobuf.Int32Value` Well-Known-Type. +message Int32Rules { + // `const` requires the field value to exactly match the specified value. If + // the field value doesn't match, an error message is generated. + // + // ```proto + // message MyInt32 { + // // value must equal 42 + // int32 value = 1 [(buf.validate.field).int32.const = 42]; + // } + // ``` + optional int32 const = 1 [(priv.field).cel = { + id: "int32.const", + expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''", + }]; + oneof less_than { + // `lt` requires the field value to be less than the specified value (field + // < value). If the field value is equal to or greater than the specified + // value, an error message is generated. + // + // ```proto + // message MyInt32 { + // // value must be less than 10 + // int32 value = 1 [(buf.validate.field).int32.lt = 10]; + // } + // ``` + int32 lt = 2 [(priv.field).cel = { + id: "int32.lt", + expression: + "!has(rules.gte) && !has(rules.gt) && this >= rules.lt" + "? 'value must be less than %s'.format([rules.lt]) : ''" + }]; + + // `lte` requires the field value to be less than or equal to the specified + // value (field <= value). If the field value is greater than the specified + // value, an error message is generated. + // + // ```proto + // message MyInt32 { + // // value must be less than or equal to 10 + // int32 value = 1 [(buf.validate.field).int32.lte = 10]; + // } + // ``` + int32 lte = 3 [(priv.field).cel = { + id: "int32.lte", + expression: + "!has(rules.gte) && !has(rules.gt) && this > rules.lte" + "? 'value must be less than or equal to %s'.format([rules.lte]) : ''" + }]; + } + oneof greater_than { + // `gt` requires the field value to be greater than the specified value + // (exclusive). If the value of `gt` is larger than a specified `lt` or + // `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MyInt32 { + // // value must be greater than 5 [int32.gt] + // int32 value = 1 [(buf.validate.field).int32.gt = 5]; + // + // // value must be greater than 5 and less than 10 [int32.gt_lt] + // int32 other_value = 2 [(buf.validate.field).int32 = { gt: 5, lt: 10 }]; + // + // // value must be greater than 10 or less than 5 [int32.gt_lt_exclusive] + // int32 another_value = 3 [(buf.validate.field).int32 = { gt: 10, lt: 5 }]; + // } + // ``` + int32 gt = 4 [ + (priv.field).cel = { + id: "int32.gt", + expression: + "!has(rules.lt) && !has(rules.lte) && this <= rules.gt" + "? 'value must be greater than %s'.format([rules.gt]) : ''" + }, + (priv.field).cel = { + id: "int32.gt_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gt && (this >= rules.lt || this <= rules.gt)" + "? 'value must be greater than %s and less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "int32.gt_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gt && (rules.lt <= this && this <= rules.gt)" + "? 'value must be greater than %s or less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "int32.gt_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gt && (this > rules.lte || this <= rules.gt)" + "? 'value must be greater than %s and less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "int32.gt_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gt && (rules.lte < this && this <= rules.gt)" + "? 'value must be greater than %s or less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + } + ]; + + // `gte` requires the field value to be greater than or equal to the specified value + // (exclusive). If the value of `gte` is larger than a specified `lt` or + // `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MyInt32 { + // // value must be greater than or equal to 5 [int32.gte] + // int32 value = 1 [(buf.validate.field).int32.gte = 5]; + // + // // value must be greater than or equal to 5 and less than 10 [int32.gte_lt] + // int32 other_value = 2 [(buf.validate.field).int32 = { gte: 5, lt: 10 }]; + // + // // value must be greater than or equal to 10 or less than 5 [int32.gte_lt_exclusive] + // int32 another_value = 3 [(buf.validate.field).int32 = { gte: 10, lt: 5 }]; + // } + // ``` + int32 gte = 5 [ + (priv.field).cel = { + id: "int32.gte", + expression: + "!has(rules.lt) && !has(rules.lte) && this < rules.gte" + "? 'value must be greater than or equal to %s'.format([rules.gte]) : ''" + }, + (priv.field).cel = { + id: "int32.gte_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gte && (this >= rules.lt || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "int32.gte_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gte && (rules.lt <= this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "int32.gte_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gte && (this > rules.lte || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "int32.gte_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gte && (rules.lte < this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + } + ]; + } + + // `in` requires the field value to be equal to one of the specified values. + // If the field value isn't one of the specified values, an error message is + // generated. + // + // ```proto + // message MyInt32 { + // // value must be in list [1, 2, 3] + // repeated int32 value = 1 (buf.validate.field).int32 = { in: [1, 2, 3] }; + // } + // ``` + repeated int32 in = 6 [(priv.field).cel = { + id: "int32.in", + expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''", + }]; + + // `not_in` requires the field value to not be equal to any of the specified + // values. If the field value is one of the specified values, an error message + // is generated. + // + // ```proto + // message MyInt32 { + // // value must not be in list [1, 2, 3] + // repeated int32 value = 1 (buf.validate.field).int32 = { not_in: [1, 2, 3] }; + // } + // ``` + repeated int32 not_in = 7 [(priv.field).cel = { + id: "int32.not_in", + expression: "this in rules.not_in ? 'value must not be in list %s'.format([rules.not_in]) : ''", + }]; +} + +// Int64Rules describes the constraints applied to `int64` values. These +// rules may also be applied to the `google.protobuf.Int64Value` Well-Known-Type. +message Int64Rules { + // `const` requires the field value to exactly match the specified value. If + // the field value doesn't match, an error message is generated. + // + // ```proto + // message MyInt64 { + // // value must equal 42 + // int64 value = 1 [(buf.validate.field).int64.const = 42]; + // } + // ``` + optional int64 const = 1 [(priv.field).cel = { + id: "int64.const", + expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''", + }]; + oneof less_than { + // `lt` requires the field value to be less than the specified value (field < + // value). If the field value is equal to or greater than the specified value, + // an error message is generated. + // + // ```proto + // message MyInt64 { + // // value must be less than 10 + // int64 value = 1 [(buf.validate.field).int64.lt = 10]; + // } + // ``` + int64 lt = 2 [(priv.field).cel = { + id: "int64.lt", + expression: + "!has(rules.gte) && !has(rules.gt) && this >= rules.lt" + "? 'value must be less than %s'.format([rules.lt]) : ''" + }]; + + // `lte` requires the field value to be less than or equal to the specified + // value (field <= value). If the field value is greater than the specified + // value, an error message is generated. + // + // ```proto + // message MyInt64 { + // // value must be less than or equal to 10 + // int64 value = 1 [(buf.validate.field).int64.lte = 10]; + // } + // ``` + int64 lte = 3 [(priv.field).cel = { + id: "int64.lte", + expression: + "!has(rules.gte) && !has(rules.gt) && this > rules.lte" + "? 'value must be less than or equal to %s'.format([rules.lte]) : ''" + }]; + } + oneof greater_than { + // `gt` requires the field value to be greater than the specified value + // (exclusive). If the value of `gt` is larger than a specified `lt` or + // `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MyInt64 { + // // value must be greater than 5 [int64.gt] + // int64 value = 1 [(buf.validate.field).int64.gt = 5]; + // + // // value must be greater than 5 and less than 10 [int64.gt_lt] + // int64 other_value = 2 [(buf.validate.field).int64 = { gt: 5, lt: 10 }]; + // + // // value must be greater than 10 or less than 5 [int64.gt_lt_exclusive] + // int64 another_value = 3 [(buf.validate.field).int64 = { gt: 10, lt: 5 }]; + // } + // ``` + int64 gt = 4 [ + (priv.field).cel = { + id: "int64.gt", + expression: + "!has(rules.lt) && !has(rules.lte) && this <= rules.gt" + "? 'value must be greater than %s'.format([rules.gt]) : ''" + }, + (priv.field).cel = { + id: "int64.gt_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gt && (this >= rules.lt || this <= rules.gt)" + "? 'value must be greater than %s and less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "int64.gt_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gt && (rules.lt <= this && this <= rules.gt)" + "? 'value must be greater than %s or less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "int64.gt_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gt && (this > rules.lte || this <= rules.gt)" + "? 'value must be greater than %s and less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "int64.gt_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gt && (rules.lte < this && this <= rules.gt)" + "? 'value must be greater than %s or less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + } + ]; + + // `gte` requires the field value to be greater than or equal to the specified + // value (exclusive). If the value of `gte` is larger than a specified `lt` + // or `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MyInt64 { + // // value must be greater than or equal to 5 [int64.gte] + // int64 value = 1 [(buf.validate.field).int64.gte = 5]; + // + // // value must be greater than or equal to 5 and less than 10 [int64.gte_lt] + // int64 other_value = 2 [(buf.validate.field).int64 = { gte: 5, lt: 10 }]; + // + // // value must be greater than or equal to 10 or less than 5 [int64.gte_lt_exclusive] + // int64 another_value = 3 [(buf.validate.field).int64 = { gte: 10, lt: 5 }]; + // } + // ``` + int64 gte = 5 [ + (priv.field).cel = { + id: "int64.gte", + expression: + "!has(rules.lt) && !has(rules.lte) && this < rules.gte" + "? 'value must be greater than or equal to %s'.format([rules.gte]) : ''" + }, + (priv.field).cel = { + id: "int64.gte_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gte && (this >= rules.lt || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "int64.gte_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gte && (rules.lt <= this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "int64.gte_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gte && (this > rules.lte || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "int64.gte_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gte && (rules.lte < this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + } + ]; + } + + // `in` requires the field value to be equal to one of the specified values. + // If the field value isn't one of the specified values, an error message is + // generated. + // + // ```proto + // message MyInt64 { + // // value must be in list [1, 2, 3] + // repeated int64 value = 1 (buf.validate.field).int64 = { in: [1, 2, 3] }; + // } + // ``` + repeated int64 in = 6 [(priv.field).cel = { + id: "int64.in", + expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''", + }]; + + // `not_in` requires the field value to not be equal to any of the specified + // values. If the field value is one of the specified values, an error + // message is generated. + // + // ```proto + // message MyInt64 { + // // value must not be in list [1, 2, 3] + // repeated int64 value = 1 (buf.validate.field).int64 = { not_in: [1, 2, 3] }; + // } + // ``` + repeated int64 not_in = 7 [(priv.field).cel = { + id: "int64.not_in", + expression: "this in rules.not_in ? 'value must not be in list %s'.format([rules.not_in]) : ''", + }]; +} + +// UInt32Rules describes the constraints applied to `uint32` values. These +// rules may also be applied to the `google.protobuf.UInt32Value` Well-Known-Type. +message UInt32Rules { + // `const` requires the field value to exactly match the specified value. If + // the field value doesn't match, an error message is generated. + // + // ```proto + // message MyUInt32 { + // // value must equal 42 + // uint32 value = 1 [(buf.validate.field).uint32.const = 42]; + // } + // ``` + optional uint32 const = 1 [(priv.field).cel = { + id: "uint32.const", + expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''", + }]; + oneof less_than { + // `lt` requires the field value to be less than the specified value (field < + // value). If the field value is equal to or greater than the specified value, + // an error message is generated. + // + // ```proto + // message MyUInt32 { + // // value must be less than 10 + // uint32 value = 1 [(buf.validate.field).uint32.lt = 10]; + // } + // ``` + uint32 lt = 2 [(priv.field).cel = { + id: "uint32.lt", + expression: + "!has(rules.gte) && !has(rules.gt) && this >= rules.lt" + "? 'value must be less than %s'.format([rules.lt]) : ''" + }]; + + // `lte` requires the field value to be less than or equal to the specified + // value (field <= value). If the field value is greater than the specified + // value, an error message is generated. + // + // ```proto + // message MyUInt32 { + // // value must be less than or equal to 10 + // uint32 value = 1 [(buf.validate.field).uint32.lte = 10]; + // } + // ``` + uint32 lte = 3 [(priv.field).cel = { + id: "uint32.lte", + expression: + "!has(rules.gte) && !has(rules.gt) && this > rules.lte" + "? 'value must be less than or equal to %s'.format([rules.lte]) : ''" + }]; + } + oneof greater_than { + // `gt` requires the field value to be greater than the specified value + // (exclusive). If the value of `gt` is larger than a specified `lt` or + // `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MyUInt32 { + // // value must be greater than 5 [uint32.gt] + // uint32 value = 1 [(buf.validate.field).uint32.gt = 5]; + // + // // value must be greater than 5 and less than 10 [uint32.gt_lt] + // uint32 other_value = 2 [(buf.validate.field).uint32 = { gt: 5, lt: 10 }]; + // + // // value must be greater than 10 or less than 5 [uint32.gt_lt_exclusive] + // uint32 another_value = 3 [(buf.validate.field).uint32 = { gt: 10, lt: 5 }]; + // } + // ``` + uint32 gt = 4 [ + (priv.field).cel = { + id: "uint32.gt", + expression: + "!has(rules.lt) && !has(rules.lte) && this <= rules.gt" + "? 'value must be greater than %s'.format([rules.gt]) : ''" + }, + (priv.field).cel = { + id: "uint32.gt_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gt && (this >= rules.lt || this <= rules.gt)" + "? 'value must be greater than %s and less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "uint32.gt_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gt && (rules.lt <= this && this <= rules.gt)" + "? 'value must be greater than %s or less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "uint32.gt_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gt && (this > rules.lte || this <= rules.gt)" + "? 'value must be greater than %s and less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "uint32.gt_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gt && (rules.lte < this && this <= rules.gt)" + "? 'value must be greater than %s or less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + } + ]; + + // `gte` requires the field value to be greater than or equal to the specified + // value (exclusive). If the value of `gte` is larger than a specified `lt` + // or `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MyUInt32 { + // // value must be greater than or equal to 5 [uint32.gte] + // uint32 value = 1 [(buf.validate.field).uint32.gte = 5]; + // + // // value must be greater than or equal to 5 and less than 10 [uint32.gte_lt] + // uint32 other_value = 2 [(buf.validate.field).uint32 = { gte: 5, lt: 10 }]; + // + // // value must be greater than or equal to 10 or less than 5 [uint32.gte_lt_exclusive] + // uint32 another_value = 3 [(buf.validate.field).uint32 = { gte: 10, lt: 5 }]; + // } + // ``` + uint32 gte = 5 [ + (priv.field).cel = { + id: "uint32.gte", + expression: + "!has(rules.lt) && !has(rules.lte) && this < rules.gte" + "? 'value must be greater than or equal to %s'.format([rules.gte]) : ''" + }, + (priv.field).cel = { + id: "uint32.gte_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gte && (this >= rules.lt || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "uint32.gte_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gte && (rules.lt <= this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "uint32.gte_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gte && (this > rules.lte || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "uint32.gte_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gte && (rules.lte < this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + } + ]; + } + + // `in` requires the field value to be equal to one of the specified values. + // If the field value isn't one of the specified values, an error message is + // generated. + // + // ```proto + // message MyUInt32 { + // // value must be in list [1, 2, 3] + // repeated uint32 value = 1 (buf.validate.field).uint32 = { in: [1, 2, 3] }; + // } + // ``` + repeated uint32 in = 6 [(priv.field).cel = { + id: "uint32.in", + expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''", + }]; + + // `not_in` requires the field value to not be equal to any of the specified + // values. If the field value is one of the specified values, an error + // message is generated. + // + // ```proto + // message MyUInt32 { + // // value must not be in list [1, 2, 3] + // repeated uint32 value = 1 (buf.validate.field).uint32 = { not_in: [1, 2, 3] }; + // } + // ``` + repeated uint32 not_in = 7 [(priv.field).cel = { + id: "uint32.not_in", + expression: "this in rules.not_in ? 'value must not be in list %s'.format([rules.not_in]) : ''", + }]; +} + +// UInt64Rules describes the constraints applied to `uint64` values. These +// rules may also be applied to the `google.protobuf.UInt64Value` Well-Known-Type. +message UInt64Rules { + // `const` requires the field value to exactly match the specified value. If + // the field value doesn't match, an error message is generated. + // + // ```proto + // message MyUInt64 { + // // value must equal 42 + // uint64 value = 1 [(buf.validate.field).uint64.const = 42]; + // } + // ``` + optional uint64 const = 1 [(priv.field).cel = { + id: "uint64.const", + expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''", + }]; + oneof less_than { + // `lt` requires the field value to be less than the specified value (field < + // value). If the field value is equal to or greater than the specified value, + // an error message is generated. + // + // ```proto + // message MyUInt64 { + // // value must be less than 10 + // uint64 value = 1 [(buf.validate.field).uint64.lt = 10]; + // } + // ``` + uint64 lt = 2 [(priv.field).cel = { + id: "uint64.lt", + expression: + "!has(rules.gte) && !has(rules.gt) && this >= rules.lt" + "? 'value must be less than %s'.format([rules.lt]) : ''" + }]; + + // `lte` requires the field value to be less than or equal to the specified + // value (field <= value). If the field value is greater than the specified + // value, an error message is generated. + // + // ```proto + // message MyUInt64 { + // // value must be less than or equal to 10 + // uint64 value = 1 [(buf.validate.field).uint64.lte = 10]; + // } + // ``` + uint64 lte = 3 [(priv.field).cel = { + id: "uint64.lte", + expression: + "!has(rules.gte) && !has(rules.gt) && this > rules.lte" + "? 'value must be less than or equal to %s'.format([rules.lte]) : ''" + }]; + } + oneof greater_than { + // `gt` requires the field value to be greater than the specified value + // (exclusive). If the value of `gt` is larger than a specified `lt` or + // `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MyUInt64 { + // // value must be greater than 5 [uint64.gt] + // uint64 value = 1 [(buf.validate.field).uint64.gt = 5]; + // + // // value must be greater than 5 and less than 10 [uint64.gt_lt] + // uint64 other_value = 2 [(buf.validate.field).uint64 = { gt: 5, lt: 10 }]; + // + // // value must be greater than 10 or less than 5 [uint64.gt_lt_exclusive] + // uint64 another_value = 3 [(buf.validate.field).uint64 = { gt: 10, lt: 5 }]; + // } + // ``` + uint64 gt = 4 [ + (priv.field).cel = { + id: "uint64.gt", + expression: + "!has(rules.lt) && !has(rules.lte) && this <= rules.gt" + "? 'value must be greater than %s'.format([rules.gt]) : ''" + }, + (priv.field).cel = { + id: "uint64.gt_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gt && (this >= rules.lt || this <= rules.gt)" + "? 'value must be greater than %s and less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "uint64.gt_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gt && (rules.lt <= this && this <= rules.gt)" + "? 'value must be greater than %s or less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "uint64.gt_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gt && (this > rules.lte || this <= rules.gt)" + "? 'value must be greater than %s and less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "uint64.gt_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gt && (rules.lte < this && this <= rules.gt)" + "? 'value must be greater than %s or less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + } + ]; + + // `gte` requires the field value to be greater than or equal to the specified + // value (exclusive). If the value of `gte` is larger than a specified `lt` + // or `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MyUInt64 { + // // value must be greater than or equal to 5 [uint64.gte] + // uint64 value = 1 [(buf.validate.field).uint64.gte = 5]; + // + // // value must be greater than or equal to 5 and less than 10 [uint64.gte_lt] + // uint64 other_value = 2 [(buf.validate.field).uint64 = { gte: 5, lt: 10 }]; + // + // // value must be greater than or equal to 10 or less than 5 [uint64.gte_lt_exclusive] + // uint64 another_value = 3 [(buf.validate.field).uint64 = { gte: 10, lt: 5 }]; + // } + // ``` + uint64 gte = 5 [ + (priv.field).cel = { + id: "uint64.gte", + expression: + "!has(rules.lt) && !has(rules.lte) && this < rules.gte" + "? 'value must be greater than or equal to %s'.format([rules.gte]) : ''" + }, + (priv.field).cel = { + id: "uint64.gte_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gte && (this >= rules.lt || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "uint64.gte_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gte && (rules.lt <= this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "uint64.gte_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gte && (this > rules.lte || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "uint64.gte_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gte && (rules.lte < this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + } + ]; + } + // `in` requires the field value to be equal to one of the specified values. + // If the field value isn't one of the specified values, an error message is + // generated. + // + // ```proto + // message MyUInt64 { + // // value must be in list [1, 2, 3] + // repeated uint64 value = 1 (buf.validate.field).uint64 = { in: [1, 2, 3] }; + // } + // ``` + repeated uint64 in = 6 [(priv.field).cel = { + id: "uint64.in", + expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''", + }]; + + // `not_in` requires the field value to not be equal to any of the specified + // values. If the field value is one of the specified values, an error + // message is generated. + // + // ```proto + // message MyUInt64 { + // // value must not be in list [1, 2, 3] + // repeated uint64 value = 1 (buf.validate.field).uint64 = { not_in: [1, 2, 3] }; + // } + // ``` + repeated uint64 not_in = 7 [(priv.field).cel = { + id: "uint64.not_in", + expression: "this in rules.not_in ? 'value must not be in list %s'.format([rules.not_in]) : ''", + }]; +} + +// SInt32Rules describes the constraints applied to `sint32` values. +message SInt32Rules { + // `const` requires the field value to exactly match the specified value. If + // the field value doesn't match, an error message is generated. + // + // ```proto + // message MySInt32 { + // // value must equal 42 + // sint32 value = 1 [(buf.validate.field).sint32.const = 42]; + // } + // ``` + optional sint32 const = 1 [(priv.field).cel = { + id: "sint32.const", + expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''", + }]; + oneof less_than { + // `lt` requires the field value to be less than the specified value (field + // < value). If the field value is equal to or greater than the specified + // value, an error message is generated. + // + // ```proto + // message MySInt32 { + // // value must be less than 10 + // sint32 value = 1 [(buf.validate.field).sint32.lt = 10]; + // } + // ``` + sint32 lt = 2 [(priv.field).cel = { + id: "sint32.lt", + expression: + "!has(rules.gte) && !has(rules.gt) && this >= rules.lt" + "? 'value must be less than %s'.format([rules.lt]) : ''" + }]; + + // `lte` requires the field value to be less than or equal to the specified + // value (field <= value). If the field value is greater than the specified + // value, an error message is generated. + // + // ```proto + // message MySInt32 { + // // value must be less than or equal to 10 + // sint32 value = 1 [(buf.validate.field).sint32.lte = 10]; + // } + // ``` + sint32 lte = 3 [(priv.field).cel = { + id: "sint32.lte", + expression: + "!has(rules.gte) && !has(rules.gt) && this > rules.lte" + "? 'value must be less than or equal to %s'.format([rules.lte]) : ''" + }]; + } + oneof greater_than { + // `gt` requires the field value to be greater than the specified value + // (exclusive). If the value of `gt` is larger than a specified `lt` or + // `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MySInt32 { + // // value must be greater than 5 [sint32.gt] + // sint32 value = 1 [(buf.validate.field).sint32.gt = 5]; + // + // // value must be greater than 5 and less than 10 [sint32.gt_lt] + // sint32 other_value = 2 [(buf.validate.field).sint32 = { gt: 5, lt: 10 }]; + // + // // value must be greater than 10 or less than 5 [sint32.gt_lt_exclusive] + // sint32 another_value = 3 [(buf.validate.field).sint32 = { gt: 10, lt: 5 }]; + // } + // ``` + sint32 gt = 4 [ + (priv.field).cel = { + id: "sint32.gt", + expression: + "!has(rules.lt) && !has(rules.lte) && this <= rules.gt" + "? 'value must be greater than %s'.format([rules.gt]) : ''" + }, + (priv.field).cel = { + id: "sint32.gt_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gt && (this >= rules.lt || this <= rules.gt)" + "? 'value must be greater than %s and less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "sint32.gt_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gt && (rules.lt <= this && this <= rules.gt)" + "? 'value must be greater than %s or less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "sint32.gt_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gt && (this > rules.lte || this <= rules.gt)" + "? 'value must be greater than %s and less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "sint32.gt_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gt && (rules.lte < this && this <= rules.gt)" + "? 'value must be greater than %s or less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + } + ]; + + // `gte` requires the field value to be greater than or equal to the specified + // value (exclusive). If the value of `gte` is larger than a specified `lt` + // or `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MySInt32 { + // // value must be greater than or equal to 5 [sint32.gte] + // sint32 value = 1 [(buf.validate.field).sint32.gte = 5]; + // + // // value must be greater than or equal to 5 and less than 10 [sint32.gte_lt] + // sint32 other_value = 2 [(buf.validate.field).sint32 = { gte: 5, lt: 10 }]; + // + // // value must be greater than or equal to 10 or less than 5 [sint32.gte_lt_exclusive] + // sint32 another_value = 3 [(buf.validate.field).sint32 = { gte: 10, lt: 5 }]; + // } + // ``` + sint32 gte = 5 [ + (priv.field).cel = { + id: "sint32.gte", + expression: + "!has(rules.lt) && !has(rules.lte) && this < rules.gte" + "? 'value must be greater than or equal to %s'.format([rules.gte]) : ''" + }, + (priv.field).cel = { + id: "sint32.gte_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gte && (this >= rules.lt || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "sint32.gte_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gte && (rules.lt <= this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "sint32.gte_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gte && (this > rules.lte || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "sint32.gte_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gte && (rules.lte < this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + } + ]; + } + + // `in` requires the field value to be equal to one of the specified values. + // If the field value isn't one of the specified values, an error message is + // generated. + // + // ```proto + // message MySInt32 { + // // value must be in list [1, 2, 3] + // repeated sint32 value = 1 (buf.validate.field).sint32 = { in: [1, 2, 3] }; + // } + // ``` + repeated sint32 in = 6 [(priv.field).cel = { + id: "sint32.in", + expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''", + }]; + + // `not_in` requires the field value to not be equal to any of the specified + // values. If the field value is one of the specified values, an error + // message is generated. + // + // ```proto + // message MySInt32 { + // // value must not be in list [1, 2, 3] + // repeated sint32 value = 1 (buf.validate.field).sint32 = { not_in: [1, 2, 3] }; + // } + // ``` + repeated sint32 not_in = 7 [(priv.field).cel = { + id: "sint32.not_in", + expression: "this in rules.not_in ? 'value must not be in list %s'.format([rules.not_in]) : ''", + }]; +} + +// SInt64Rules describes the constraints applied to `sint64` values. +message SInt64Rules { + // `const` requires the field value to exactly match the specified value. If + // the field value doesn't match, an error message is generated. + // + // ```proto + // message MySInt64 { + // // value must equal 42 + // sint64 value = 1 [(buf.validate.field).sint64.const = 42]; + // } + // ``` + optional sint64 const = 1 [(priv.field).cel = { + id: "sint64.const", + expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''", + }]; + oneof less_than { + // `lt` requires the field value to be less than the specified value (field + // < value). If the field value is equal to or greater than the specified + // value, an error message is generated. + // + // ```proto + // message MySInt64 { + // // value must be less than 10 + // sint64 value = 1 [(buf.validate.field).sint64.lt = 10]; + // } + // ``` + sint64 lt = 2 [(priv.field).cel = { + id: "sint64.lt", + expression: + "!has(rules.gte) && !has(rules.gt) && this >= rules.lt" + "? 'value must be less than %s'.format([rules.lt]) : ''" + }]; + + // `lte` requires the field value to be less than or equal to the specified + // value (field <= value). If the field value is greater than the specified + // value, an error message is generated. + // + // ```proto + // message MySInt64 { + // // value must be less than or equal to 10 + // sint64 value = 1 [(buf.validate.field).sint64.lte = 10]; + // } + // ``` + sint64 lte = 3 [(priv.field).cel = { + id: "sint64.lte", + expression: + "!has(rules.gte) && !has(rules.gt) && this > rules.lte" + "? 'value must be less than or equal to %s'.format([rules.lte]) : ''" + }]; + } + oneof greater_than { + // `gt` requires the field value to be greater than the specified value + // (exclusive). If the value of `gt` is larger than a specified `lt` or + // `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MySInt64 { + // // value must be greater than 5 [sint64.gt] + // sint64 value = 1 [(buf.validate.field).sint64.gt = 5]; + // + // // value must be greater than 5 and less than 10 [sint64.gt_lt] + // sint64 other_value = 2 [(buf.validate.field).sint64 = { gt: 5, lt: 10 }]; + // + // // value must be greater than 10 or less than 5 [sint64.gt_lt_exclusive] + // sint64 another_value = 3 [(buf.validate.field).sint64 = { gt: 10, lt: 5 }]; + // } + // ``` + sint64 gt = 4 [ + (priv.field).cel = { + id: "sint64.gt", + expression: + "!has(rules.lt) && !has(rules.lte) && this <= rules.gt" + "? 'value must be greater than %s'.format([rules.gt]) : ''" + }, + (priv.field).cel = { + id: "sint64.gt_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gt && (this >= rules.lt || this <= rules.gt)" + "? 'value must be greater than %s and less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "sint64.gt_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gt && (rules.lt <= this && this <= rules.gt)" + "? 'value must be greater than %s or less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "sint64.gt_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gt && (this > rules.lte || this <= rules.gt)" + "? 'value must be greater than %s and less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "sint64.gt_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gt && (rules.lte < this && this <= rules.gt)" + "? 'value must be greater than %s or less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + } + ]; + + // `gte` requires the field value to be greater than or equal to the specified + // value (exclusive). If the value of `gte` is larger than a specified `lt` + // or `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MySInt64 { + // // value must be greater than or equal to 5 [sint64.gte] + // sint64 value = 1 [(buf.validate.field).sint64.gte = 5]; + // + // // value must be greater than or equal to 5 and less than 10 [sint64.gte_lt] + // sint64 other_value = 2 [(buf.validate.field).sint64 = { gte: 5, lt: 10 }]; + // + // // value must be greater than or equal to 10 or less than 5 [sint64.gte_lt_exclusive] + // sint64 another_value = 3 [(buf.validate.field).sint64 = { gte: 10, lt: 5 }]; + // } + // ``` + sint64 gte = 5 [ + (priv.field).cel = { + id: "sint64.gte", + expression: + "!has(rules.lt) && !has(rules.lte) && this < rules.gte" + "? 'value must be greater than or equal to %s'.format([rules.gte]) : ''" + }, + (priv.field).cel = { + id: "sint64.gte_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gte && (this >= rules.lt || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "sint64.gte_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gte && (rules.lt <= this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "sint64.gte_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gte && (this > rules.lte || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "sint64.gte_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gte && (rules.lte < this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + } + ]; + } + + // `in` requires the field value to be equal to one of the specified values. + // If the field value isn't one of the specified values, an error message + // is generated. + // + // ```proto + // message MySInt64 { + // // value must be in list [1, 2, 3] + // repeated sint64 value = 1 (buf.validate.field).sint64 = { in: [1, 2, 3] }; + // } + // ``` + repeated sint64 in = 6 [(priv.field).cel = { + id: "sint64.in", + expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''", + }]; + + // `not_in` requires the field value to not be equal to any of the specified + // values. If the field value is one of the specified values, an error + // message is generated. + // + // ```proto + // message MySInt64 { + // // value must not be in list [1, 2, 3] + // repeated sint64 value = 1 (buf.validate.field).sint64 = { not_in: [1, 2, 3] }; + // } + // ``` + repeated sint64 not_in = 7 [(priv.field).cel = { + id: "sint64.not_in", + expression: "this in rules.not_in ? 'value must not be in list %s'.format([rules.not_in]) : ''", + }]; +} + +// Fixed32Rules describes the constraints applied to `fixed32` values. +message Fixed32Rules { + // `const` requires the field value to exactly match the specified value. + // If the field value doesn't match, an error message is generated. + // + // ```proto + // message MyFixed32 { + // // value must equal 42 + // fixed32 value = 1 [(buf.validate.field).fixed32.const = 42]; + // } + // ``` + optional fixed32 const = 1 [(priv.field).cel = { + id: "fixed32.const", + expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''", + }]; + oneof less_than { + // `lt` requires the field value to be less than the specified value (field < + // value). If the field value is equal to or greater than the specified value, + // an error message is generated. + // + // ```proto + // message MyFixed32 { + // // value must be less than 10 + // fixed32 value = 1 [(buf.validate.field).fixed32.lt = 10]; + // } + // ``` + fixed32 lt = 2 [(priv.field).cel = { + id: "fixed32.lt", + expression: + "!has(rules.gte) && !has(rules.gt) && this >= rules.lt" + "? 'value must be less than %s'.format([rules.lt]) : ''" + }]; + + // `lte` requires the field value to be less than or equal to the specified + // value (field <= value). If the field value is greater than the specified + // value, an error message is generated. + // + // ```proto + // message MyFixed32 { + // // value must be less than or equal to 10 + // fixed32 value = 1 [(buf.validate.field).fixed32.lte = 10]; + // } + // ``` + fixed32 lte = 3 [(priv.field).cel = { + id: "fixed32.lte", + expression: + "!has(rules.gte) && !has(rules.gt) && this > rules.lte" + "? 'value must be less than or equal to %s'.format([rules.lte]) : ''" + }]; + } + oneof greater_than { + // `gt` requires the field value to be greater than the specified value + // (exclusive). If the value of `gt` is larger than a specified `lt` or + // `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MyFixed32 { + // // value must be greater than 5 [fixed32.gt] + // fixed32 value = 1 [(buf.validate.field).fixed32.gt = 5]; + // + // // value must be greater than 5 and less than 10 [fixed32.gt_lt] + // fixed32 other_value = 2 [(buf.validate.field).fixed32 = { gt: 5, lt: 10 }]; + // + // // value must be greater than 10 or less than 5 [fixed32.gt_lt_exclusive] + // fixed32 another_value = 3 [(buf.validate.field).fixed32 = { gt: 10, lt: 5 }]; + // } + // ``` + fixed32 gt = 4 [ + (priv.field).cel = { + id: "fixed32.gt", + expression: + "!has(rules.lt) && !has(rules.lte) && this <= rules.gt" + "? 'value must be greater than %s'.format([rules.gt]) : ''" + }, + (priv.field).cel = { + id: "fixed32.gt_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gt && (this >= rules.lt || this <= rules.gt)" + "? 'value must be greater than %s and less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "fixed32.gt_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gt && (rules.lt <= this && this <= rules.gt)" + "? 'value must be greater than %s or less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "fixed32.gt_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gt && (this > rules.lte || this <= rules.gt)" + "? 'value must be greater than %s and less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "fixed32.gt_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gt && (rules.lte < this && this <= rules.gt)" + "? 'value must be greater than %s or less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + } + ]; + + // `gte` requires the field value to be greater than or equal to the specified + // value (exclusive). If the value of `gte` is larger than a specified `lt` + // or `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MyFixed32 { + // // value must be greater than or equal to 5 [fixed32.gte] + // fixed32 value = 1 [(buf.validate.field).fixed32.gte = 5]; + // + // // value must be greater than or equal to 5 and less than 10 [fixed32.gte_lt] + // fixed32 other_value = 2 [(buf.validate.field).fixed32 = { gte: 5, lt: 10 }]; + // + // // value must be greater than or equal to 10 or less than 5 [fixed32.gte_lt_exclusive] + // fixed32 another_value = 3 [(buf.validate.field).fixed32 = { gte: 10, lt: 5 }]; + // } + // ``` + fixed32 gte = 5 [ + (priv.field).cel = { + id: "fixed32.gte", + expression: + "!has(rules.lt) && !has(rules.lte) && this < rules.gte" + "? 'value must be greater than or equal to %s'.format([rules.gte]) : ''" + }, + (priv.field).cel = { + id: "fixed32.gte_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gte && (this >= rules.lt || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "fixed32.gte_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gte && (rules.lt <= this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "fixed32.gte_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gte && (this > rules.lte || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "fixed32.gte_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gte && (rules.lte < this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + } + ]; + } + + // `in` requires the field value to be equal to one of the specified values. + // If the field value isn't one of the specified values, an error message + // is generated. + // + // ```proto + // message MyFixed32 { + // // value must be in list [1, 2, 3] + // repeated fixed32 value = 1 (buf.validate.field).fixed32 = { in: [1, 2, 3] }; + // } + // ``` + repeated fixed32 in = 6 [(priv.field).cel = { + id: "fixed32.in", + expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''", + }]; + + // `not_in` requires the field value to not be equal to any of the specified + // values. If the field value is one of the specified values, an error + // message is generated. + // + // ```proto + // message MyFixed32 { + // // value must not be in list [1, 2, 3] + // repeated fixed32 value = 1 (buf.validate.field).fixed32 = { not_in: [1, 2, 3] }; + // } + // ``` + repeated fixed32 not_in = 7 [(priv.field).cel = { + id: "fixed32.not_in", + expression: "this in rules.not_in ? 'value must not be in list %s'.format([rules.not_in]) : ''", + }]; +} + +// Fixed64Rules describes the constraints applied to `fixed64` values. +message Fixed64Rules { + // `const` requires the field value to exactly match the specified value. If + // the field value doesn't match, an error message is generated. + // + // ```proto + // message MyFixed64 { + // // value must equal 42 + // fixed64 value = 1 [(buf.validate.field).fixed64.const = 42]; + // } + // ``` + optional fixed64 const = 1 [(priv.field).cel = { + id: "fixed64.const", + expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''", + }]; + oneof less_than { + // `lt` requires the field value to be less than the specified value (field < + // value). If the field value is equal to or greater than the specified value, + // an error message is generated. + // + // ```proto + // message MyFixed64 { + // // value must be less than 10 + // fixed64 value = 1 [(buf.validate.field).fixed64.lt = 10]; + // } + // ``` + fixed64 lt = 2 [(priv.field).cel = { + id: "fixed64.lt", + expression: + "!has(rules.gte) && !has(rules.gt) && this >= rules.lt" + "? 'value must be less than %s'.format([rules.lt]) : ''" + }]; + + // `lte` requires the field value to be less than or equal to the specified + // value (field <= value). If the field value is greater than the specified + // value, an error message is generated. + // + // ```proto + // message MyFixed64 { + // // value must be less than or equal to 10 + // fixed64 value = 1 [(buf.validate.field).fixed64.lte = 10]; + // } + // ``` + fixed64 lte = 3 [(priv.field).cel = { + id: "fixed64.lte", + expression: + "!has(rules.gte) && !has(rules.gt) && this > rules.lte" + "? 'value must be less than or equal to %s'.format([rules.lte]) : ''" + }]; + } + oneof greater_than { + // `gt` requires the field value to be greater than the specified value + // (exclusive). If the value of `gt` is larger than a specified `lt` or + // `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MyFixed64 { + // // value must be greater than 5 [fixed64.gt] + // fixed64 value = 1 [(buf.validate.field).fixed64.gt = 5]; + // + // // value must be greater than 5 and less than 10 [fixed64.gt_lt] + // fixed64 other_value = 2 [(buf.validate.field).fixed64 = { gt: 5, lt: 10 }]; + // + // // value must be greater than 10 or less than 5 [fixed64.gt_lt_exclusive] + // fixed64 another_value = 3 [(buf.validate.field).fixed64 = { gt: 10, lt: 5 }]; + // } + // ``` + fixed64 gt = 4 [ + (priv.field).cel = { + id: "fixed64.gt", + expression: + "!has(rules.lt) && !has(rules.lte) && this <= rules.gt" + "? 'value must be greater than %s'.format([rules.gt]) : ''" + }, + (priv.field).cel = { + id: "fixed64.gt_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gt && (this >= rules.lt || this <= rules.gt)" + "? 'value must be greater than %s and less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "fixed64.gt_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gt && (rules.lt <= this && this <= rules.gt)" + "? 'value must be greater than %s or less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "fixed64.gt_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gt && (this > rules.lte || this <= rules.gt)" + "? 'value must be greater than %s and less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "fixed64.gt_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gt && (rules.lte < this && this <= rules.gt)" + "? 'value must be greater than %s or less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + } + ]; + + // `gte` requires the field value to be greater than or equal to the specified + // value (exclusive). If the value of `gte` is larger than a specified `lt` + // or `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MyFixed64 { + // // value must be greater than or equal to 5 [fixed64.gte] + // fixed64 value = 1 [(buf.validate.field).fixed64.gte = 5]; + // + // // value must be greater than or equal to 5 and less than 10 [fixed64.gte_lt] + // fixed64 other_value = 2 [(buf.validate.field).fixed64 = { gte: 5, lt: 10 }]; + // + // // value must be greater than or equal to 10 or less than 5 [fixed64.gte_lt_exclusive] + // fixed64 another_value = 3 [(buf.validate.field).fixed64 = { gte: 10, lt: 5 }]; + // } + // ``` + fixed64 gte = 5 [ + (priv.field).cel = { + id: "fixed64.gte", + expression: + "!has(rules.lt) && !has(rules.lte) && this < rules.gte" + "? 'value must be greater than or equal to %s'.format([rules.gte]) : ''" + }, + (priv.field).cel = { + id: "fixed64.gte_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gte && (this >= rules.lt || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "fixed64.gte_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gte && (rules.lt <= this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "fixed64.gte_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gte && (this > rules.lte || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "fixed64.gte_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gte && (rules.lte < this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + } + ]; + } + + // `in` requires the field value to be equal to one of the specified values. + // If the field value isn't one of the specified values, an error message is + // generated. + // + // ```proto + // message MyFixed64 { + // // value must be in list [1, 2, 3] + // repeated fixed64 value = 1 (buf.validate.field).fixed64 = { in: [1, 2, 3] }; + // } + // ``` + repeated fixed64 in = 6 [(priv.field).cel = { + id: "fixed64.in", + expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''", + }]; + + // `not_in` requires the field value to not be equal to any of the specified + // values. If the field value is one of the specified values, an error + // message is generated. + // + // ```proto + // message MyFixed64 { + // // value must not be in list [1, 2, 3] + // repeated fixed64 value = 1 (buf.validate.field).fixed64 = { not_in: [1, 2, 3] }; + // } + // ``` + repeated fixed64 not_in = 7 [(priv.field).cel = { + id: "fixed64.not_in", + expression: "this in rules.not_in ? 'value must not be in list %s'.format([rules.not_in]) : ''", + }]; +} + +// SFixed32Rules describes the constraints applied to `fixed32` values. +message SFixed32Rules { + // `const` requires the field value to exactly match the specified value. If + // the field value doesn't match, an error message is generated. + // + // ```proto + // message MySFixed32 { + // // value must equal 42 + // sfixed32 value = 1 [(buf.validate.field).sfixed32.const = 42]; + // } + // ``` + optional sfixed32 const = 1 [(priv.field).cel = { + id: "sfixed32.const", + expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''", + }]; + oneof less_than { + // `lt` requires the field value to be less than the specified value (field < + // value). If the field value is equal to or greater than the specified value, + // an error message is generated. + // + // ```proto + // message MySFixed32 { + // // value must be less than 10 + // sfixed32 value = 1 [(buf.validate.field).sfixed32.lt = 10]; + // } + // ``` + sfixed32 lt = 2 [(priv.field).cel = { + id: "sfixed32.lt", + expression: + "!has(rules.gte) && !has(rules.gt) && this >= rules.lt" + "? 'value must be less than %s'.format([rules.lt]) : ''" + }]; + + // `lte` requires the field value to be less than or equal to the specified + // value (field <= value). If the field value is greater than the specified + // value, an error message is generated. + // + // ```proto + // message MySFixed32 { + // // value must be less than or equal to 10 + // sfixed32 value = 1 [(buf.validate.field).sfixed32.lte = 10]; + // } + // ``` + sfixed32 lte = 3 [(priv.field).cel = { + id: "sfixed32.lte", + expression: + "!has(rules.gte) && !has(rules.gt) && this > rules.lte" + "? 'value must be less than or equal to %s'.format([rules.lte]) : ''" + }]; + } + oneof greater_than { + // `gt` requires the field value to be greater than the specified value + // (exclusive). If the value of `gt` is larger than a specified `lt` or + // `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MySFixed32 { + // // value must be greater than 5 [sfixed32.gt] + // sfixed32 value = 1 [(buf.validate.field).sfixed32.gt = 5]; + // + // // value must be greater than 5 and less than 10 [sfixed32.gt_lt] + // sfixed32 other_value = 2 [(buf.validate.field).sfixed32 = { gt: 5, lt: 10 }]; + // + // // value must be greater than 10 or less than 5 [sfixed32.gt_lt_exclusive] + // sfixed32 another_value = 3 [(buf.validate.field).sfixed32 = { gt: 10, lt: 5 }]; + // } + // ``` + sfixed32 gt = 4 [ + (priv.field).cel = { + id: "sfixed32.gt", + expression: + "!has(rules.lt) && !has(rules.lte) && this <= rules.gt" + "? 'value must be greater than %s'.format([rules.gt]) : ''" + }, + (priv.field).cel = { + id: "sfixed32.gt_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gt && (this >= rules.lt || this <= rules.gt)" + "? 'value must be greater than %s and less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "sfixed32.gt_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gt && (rules.lt <= this && this <= rules.gt)" + "? 'value must be greater than %s or less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "sfixed32.gt_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gt && (this > rules.lte || this <= rules.gt)" + "? 'value must be greater than %s and less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "sfixed32.gt_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gt && (rules.lte < this && this <= rules.gt)" + "? 'value must be greater than %s or less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + } + ]; + + // `gte` requires the field value to be greater than or equal to the specified + // value (exclusive). If the value of `gte` is larger than a specified `lt` + // or `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MySFixed32 { + // // value must be greater than or equal to 5 [sfixed32.gte] + // sfixed32 value = 1 [(buf.validate.field).sfixed32.gte = 5]; + // + // // value must be greater than or equal to 5 and less than 10 [sfixed32.gte_lt] + // sfixed32 other_value = 2 [(buf.validate.field).sfixed32 = { gte: 5, lt: 10 }]; + // + // // value must be greater than or equal to 10 or less than 5 [sfixed32.gte_lt_exclusive] + // sfixed32 another_value = 3 [(buf.validate.field).sfixed32 = { gte: 10, lt: 5 }]; + // } + // ``` + sfixed32 gte = 5 [ + (priv.field).cel = { + id: "sfixed32.gte", + expression: + "!has(rules.lt) && !has(rules.lte) && this < rules.gte" + "? 'value must be greater than or equal to %s'.format([rules.gte]) : ''" + }, + (priv.field).cel = { + id: "sfixed32.gte_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gte && (this >= rules.lt || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "sfixed32.gte_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gte && (rules.lt <= this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "sfixed32.gte_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gte && (this > rules.lte || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "sfixed32.gte_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gte && (rules.lte < this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + } + ]; + } + + // `in` requires the field value to be equal to one of the specified values. + // If the field value isn't one of the specified values, an error message is + // generated. + // + // ```proto + // message MySFixed32 { + // // value must be in list [1, 2, 3] + // repeated sfixed32 value = 1 (buf.validate.field).sfixed32 = { in: [1, 2, 3] }; + // } + // ``` + repeated sfixed32 in = 6 [(priv.field).cel = { + id: "sfixed32.in", + expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''", + }]; + + // `not_in` requires the field value to not be equal to any of the specified + // values. If the field value is one of the specified values, an error + // message is generated. + // + // ```proto + // message MySFixed32 { + // // value must not be in list [1, 2, 3] + // repeated sfixed32 value = 1 (buf.validate.field).sfixed32 = { not_in: [1, 2, 3] }; + // } + // ``` + repeated sfixed32 not_in = 7 [(priv.field).cel = { + id: "sfixed32.not_in", + expression: "this in rules.not_in ? 'value must not be in list %s'.format([rules.not_in]) : ''", + }]; +} + +// SFixed64Rules describes the constraints applied to `fixed64` values. +message SFixed64Rules { + // `const` requires the field value to exactly match the specified value. If + // the field value doesn't match, an error message is generated. + // + // ```proto + // message MySFixed64 { + // // value must equal 42 + // sfixed64 value = 1 [(buf.validate.field).sfixed64.const = 42]; + // } + // ``` + optional sfixed64 const = 1 [(priv.field).cel = { + id: "sfixed64.const", + expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''", + }]; + oneof less_than { + // `lt` requires the field value to be less than the specified value (field < + // value). If the field value is equal to or greater than the specified value, + // an error message is generated. + // + // ```proto + // message MySFixed64 { + // // value must be less than 10 + // sfixed64 value = 1 [(buf.validate.field).sfixed64.lt = 10]; + // } + // ``` + sfixed64 lt = 2 [(priv.field).cel = { + id: "sfixed64.lt", + expression: + "!has(rules.gte) && !has(rules.gt) && this >= rules.lt" + "? 'value must be less than %s'.format([rules.lt]) : ''" + }]; + + // `lte` requires the field value to be less than or equal to the specified + // value (field <= value). If the field value is greater than the specified + // value, an error message is generated. + // + // ```proto + // message MySFixed64 { + // // value must be less than or equal to 10 + // sfixed64 value = 1 [(buf.validate.field).sfixed64.lte = 10]; + // } + // ``` + sfixed64 lte = 3 [(priv.field).cel = { + id: "sfixed64.lte", + expression: + "!has(rules.gte) && !has(rules.gt) && this > rules.lte" + "? 'value must be less than or equal to %s'.format([rules.lte]) : ''" + }]; + } + oneof greater_than { + // `gt` requires the field value to be greater than the specified value + // (exclusive). If the value of `gt` is larger than a specified `lt` or + // `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MySFixed64 { + // // value must be greater than 5 [sfixed64.gt] + // sfixed64 value = 1 [(buf.validate.field).sfixed64.gt = 5]; + // + // // value must be greater than 5 and less than 10 [sfixed64.gt_lt] + // sfixed64 other_value = 2 [(buf.validate.field).sfixed64 = { gt: 5, lt: 10 }]; + // + // // value must be greater than 10 or less than 5 [sfixed64.gt_lt_exclusive] + // sfixed64 another_value = 3 [(buf.validate.field).sfixed64 = { gt: 10, lt: 5 }]; + // } + // ``` + sfixed64 gt = 4 [ + (priv.field).cel = { + id: "sfixed64.gt", + expression: + "!has(rules.lt) && !has(rules.lte) && this <= rules.gt" + "? 'value must be greater than %s'.format([rules.gt]) : ''" + }, + (priv.field).cel = { + id: "sfixed64.gt_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gt && (this >= rules.lt || this <= rules.gt)" + "? 'value must be greater than %s and less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "sfixed64.gt_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gt && (rules.lt <= this && this <= rules.gt)" + "? 'value must be greater than %s or less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "sfixed64.gt_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gt && (this > rules.lte || this <= rules.gt)" + "? 'value must be greater than %s and less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "sfixed64.gt_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gt && (rules.lte < this && this <= rules.gt)" + "? 'value must be greater than %s or less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + } + ]; + + // `gte` requires the field value to be greater than or equal to the specified + // value (exclusive). If the value of `gte` is larger than a specified `lt` + // or `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MySFixed64 { + // // value must be greater than or equal to 5 [sfixed64.gte] + // sfixed64 value = 1 [(buf.validate.field).sfixed64.gte = 5]; + // + // // value must be greater than or equal to 5 and less than 10 [sfixed64.gte_lt] + // sfixed64 other_value = 2 [(buf.validate.field).sfixed64 = { gte: 5, lt: 10 }]; + // + // // value must be greater than or equal to 10 or less than 5 [sfixed64.gte_lt_exclusive] + // sfixed64 another_value = 3 [(buf.validate.field).sfixed64 = { gte: 10, lt: 5 }]; + // } + // ``` + sfixed64 gte = 5 [ + (priv.field).cel = { + id: "sfixed64.gte", + expression: + "!has(rules.lt) && !has(rules.lte) && this < rules.gte" + "? 'value must be greater than or equal to %s'.format([rules.gte]) : ''" + }, + (priv.field).cel = { + id: "sfixed64.gte_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gte && (this >= rules.lt || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "sfixed64.gte_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gte && (rules.lt <= this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "sfixed64.gte_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gte && (this > rules.lte || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "sfixed64.gte_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gte && (rules.lte < this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + } + ]; + } + + // `in` requires the field value to be equal to one of the specified values. + // If the field value isn't one of the specified values, an error message is + // generated. + // + // ```proto + // message MySFixed64 { + // // value must be in list [1, 2, 3] + // repeated sfixed64 value = 1 (buf.validate.field).sfixed64 = { in: [1, 2, 3] }; + // } + // ``` + repeated sfixed64 in = 6 [(priv.field).cel = { + id: "sfixed64.in", + expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''", + }]; + + // `not_in` requires the field value to not be equal to any of the specified + // values. If the field value is one of the specified values, an error + // message is generated. + // + // ```proto + // message MySFixed64 { + // // value must not be in list [1, 2, 3] + // repeated sfixed64 value = 1 (buf.validate.field).sfixed64 = { not_in: [1, 2, 3] }; + // } + // ``` + repeated sfixed64 not_in = 7 [(priv.field).cel = { + id: "sfixed64.not_in", + expression: "this in rules.not_in ? 'value must not be in list %s'.format([rules.not_in]) : ''", + }]; +} + +// BoolRules describes the constraints applied to `bool` values. These rules +// may also be applied to the `google.protobuf.BoolValue` Well-Known-Type. +message BoolRules { + // `const` requires the field value to exactly match the specified boolean value. + // If the field value doesn't match, an error message is generated. + // + // ```proto + // message MyBool { + // // value must equal true + // bool value = 1 [(buf.validate.field).bool.const = true]; + // } + // ``` + optional bool const = 1 [(priv.field).cel = { + id: "bool.const", + expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''", + }]; +} + +// StringRules describes the constraints applied to `string` values These +// rules may also be applied to the `google.protobuf.StringValue` Well-Known-Type. +message StringRules { + // `const` requires the field value to exactly match the specified value. If + // the field value doesn't match, an error message is generated. + // + // ```proto + // message MyString { + // // value must equal `hello` + // string value = 1 [(buf.validate.field).string.const = "hello"]; + // } + // ``` + optional string const = 1 [(priv.field).cel = { + id: "string.const", + expression: "this != rules.const ? 'value must equal `%s`'.format([rules.const]) : ''" + }]; + + // `len` dictates that the field value must have the specified + // number of characters (Unicode code points), which may differ from the number + // of bytes in the string. If the field value does not meet the specified + // length, an error message will be generated. + // + // ```proto + // message MyString { + // // value length must be 5 characters + // string value = 1 [(buf.validate.field).string.len = 5]; + // } + // ``` + optional uint64 len = 19 [(priv.field).cel = { + id: "string.len", + expression: "uint(this.size()) != rules.len ? 'value length must be %s characters'.format([rules.len]) : ''" + }]; + + // `min_len` specifies that the field value must have at least the specified + // number of characters (Unicode code points), which may differ from the number + // of bytes in the string. If the field value contains fewer characters, an error + // message will be generated. + // + // ```proto + // message MyString { + // // value length must be at least 3 characters + // string value = 1 [(buf.validate.field).string.min_len = 3]; + // } + // ``` + optional uint64 min_len = 2 [(priv.field).cel = { + id: "string.min_len", + expression: "uint(this.size()) < rules.min_len ? 'value length must be at least %s characters'.format([rules.min_len]) : ''" + }]; + + // `max_len` specifies that the field value must have no more than the specified + // number of characters (Unicode code points), which may differ from the + // number of bytes in the string. If the field value contains more characters, + // an error message will be generated. + // + // ```proto + // message MyString { + // // value length must be at most 10 characters + // string value = 1 [(buf.validate.field).string.max_len = 10]; + // } + // ``` + optional uint64 max_len = 3 [(priv.field).cel = { + id: "string.max_len", + expression: "uint(this.size()) > rules.max_len ? 'value length must be at most %s characters'.format([rules.max_len]) : ''" + }]; + + // `len_bytes` dictates that the field value must have the specified number of + // bytes. If the field value does not match the specified length in bytes, + // an error message will be generated. + // + // ```proto + // message MyString { + // // value length must be 6 bytes + // string value = 1 [(buf.validate.field).string.len_bytes = 6]; + // } + // ``` + optional uint64 len_bytes = 20 [(priv.field).cel = { + id: "string.len_bytes", + expression: "uint(bytes(this).size()) != rules.len_bytes ? 'value length must be %s bytes'.format([rules.len_bytes]) : ''" + }]; + + // `min_bytes` specifies that the field value must have at least the specified + // number of bytes. If the field value contains fewer bytes, an error message + // will be generated. + // + // ```proto + // message MyString { + // // value length must be at least 4 bytes + // string value = 1 [(buf.validate.field).string.min_bytes = 4]; + // } + // + // ``` + optional uint64 min_bytes = 4 [(priv.field).cel = { + id: "string.min_bytes", + expression: "uint(bytes(this).size()) < rules.min_bytes ? 'value length must be at least %s bytes'.format([rules.min_bytes]) : ''" + }]; + + // `max_bytes` specifies that the field value must have no more than the + //specified number of bytes. If the field value contains more bytes, an + // error message will be generated. + // + // ```proto + // message MyString { + // // value length must be at most 8 bytes + // string value = 1 [(buf.validate.field).string.max_bytes = 8]; + // } + // ``` + optional uint64 max_bytes = 5 [(priv.field).cel = { + id: "string.max_bytes", + expression: "uint(bytes(this).size()) > rules.max_bytes ? 'value length must be at most %s bytes'.format([rules.max_bytes]) : ''", + }]; + + // `pattern` specifies that the field value must match the specified + // regular expression (RE2 syntax), with the expression provided without any + // delimiters. If the field value doesn't match the regular expression, an + // error message will be generated. + // + // ```proto + // message MyString { + // // value does not match regex pattern `^[a-zA-Z]//$` + // string value = 1 [(buf.validate.field).string.pattern = "^[a-zA-Z]//$"]; + // } + // ``` + optional string pattern = 6 [(priv.field).cel = { + id: "string.pattern", + expression: "!this.matches(rules.pattern) ? 'value does not match regex pattern `%s`'.format([rules.pattern]) : ''" + }]; + + // `prefix` specifies that the field value must have the + //specified substring at the beginning of the string. If the field value + // doesn't start with the specified prefix, an error message will be + // generated. + // + // ```proto + // message MyString { + // // value does not have prefix `pre` + // string value = 1 [(buf.validate.field).string.prefix = "pre"]; + // } + // ``` + optional string prefix = 7 [(priv.field).cel = { + id: "string.prefix", + expression: "!this.startsWith(rules.prefix) ? 'value does not have prefix `%s`'.format([rules.prefix]) : ''" + }]; + + // `suffix` specifies that the field value must have the + //specified substring at the end of the string. If the field value doesn't + // end with the specified suffix, an error message will be generated. + // + // ```proto + // message MyString { + // // value does not have suffix `post` + // string value = 1 [(buf.validate.field).string.suffix = "post"]; + // } + // ``` + optional string suffix = 8 [(priv.field).cel = { + id: "string.suffix", + expression: "!this.endsWith(rules.suffix) ? 'value does not have suffix `%s`'.format([rules.suffix]) : ''" + }]; + + // `contains` specifies that the field value must have the + //specified substring anywhere in the string. If the field value doesn't + // contain the specified substring, an error message will be generated. + // + // ```proto + // message MyString { + // // value does not contain substring `inside`. + // string value = 1 [(buf.validate.field).string.contains = "inside"]; + // } + // ``` + optional string contains = 9 [(priv.field).cel = { + id: "string.contains", + expression: "!this.contains(rules.contains) ? 'value does not contain substring `%s`'.format([rules.contains]) : ''" + }]; + + // `not_contains` specifies that the field value must not have the + //specified substring anywhere in the string. If the field value contains + // the specified substring, an error message will be generated. + // + // ```proto + // message MyString { + // // value contains substring `inside`. + // string value = 1 [(buf.validate.field).string.not_contains = "inside"]; + // } + // ``` + optional string not_contains = 23 [(priv.field).cel = { + id: "string.not_contains", + expression: "this.contains(rules.not_contains) ? 'value contains substring `%s`'.format([rules.not_contains]) : ''" + }]; + + // `in` specifies that the field value must be equal to one of the specified + // values. If the field value isn't one of the specified values, an error + // message will be generated. + // + // ```proto + // message MyString { + // // value must be in list ["apple", "banana"] + // repeated string value = 1 [(buf.validate.field).string.in = "apple", (buf.validate.field).string.in = "banana"]; + // } + // ``` + repeated string in = 10 [(priv.field).cel = { + id: "string.in", + expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''" + }]; + + // `not_in` specifies that the field value cannot be equal to any + // of the specified values. If the field value is one of the specified values, + // an error message will be generated. + // ```proto + // message MyString { + // // value must not be in list ["orange", "grape"] + // repeated string value = 1 [(buf.validate.field).string.not_in = "orange", (buf.validate.field).string.not_in = "grape"]; + // } + // ``` + repeated string not_in = 11 [(priv.field).cel = { + id: "string.not_in", + expression: "this in rules.not_in ? 'value must not be in list %s'.format([rules.not_in]) : ''" + }]; + + // `WellKnown` rules provide advanced constraints against common string + // patterns + oneof well_known { + // `email` specifies that the field value must be a valid email address + // (addr-spec only) as defined by [RFC 5322](https://tools.ietf.org/html/rfc5322#section-3.4.1). + // If the field value isn't a valid email address, an error message will be generated. + // + // ```proto + // message MyString { + // // value must be a valid email address + // string value = 1 [(buf.validate.field).string.email = true]; + // } + // ``` + bool email = 12 [ + (priv.field).cel = { + id: "string.email", + message: "value must be a valid email address", + expression: "this == '' || this.isEmail()", + }, + (priv.field).cel = { + id: "string.email_empty", + message: "value is empty, which is not a valid email address", + expression: "this != ''", + } + ]; + + // `hostname` specifies that the field value must be a valid + // hostname as defined by [RFC 1034](https://tools.ietf.org/html/rfc1034#section-3.5). This constraint doesn't support + // internationalized domain names (IDNs). If the field value isn't a + // valid hostname, an error message will be generated. + // + // ```proto + // message MyString { + // // value must be a valid hostname + // string value = 1 [(buf.validate.field).string.hostname = true]; + // } + // ``` + bool hostname = 13 [ + (priv.field).cel = { + id: "string.hostname", + message: "value must be a valid hostname", + expression: "this == '' || this.isHostname()", + }, + (priv.field).cel = { + id: "string.hostname_empty", + message: "value is empty, which is not a valid hostname", + expression: "this != ''", + } + ]; + + // `ip` specifies that the field value must be a valid IP + // (v4 or v6) address, without surrounding square brackets for IPv6 addresses. + // If the field value isn't a valid IP address, an error message will be + // generated. + // + // ```proto + // message MyString { + // // value must be a valid IP address + // string value = 1 [(buf.validate.field).string.ip = true]; + // } + // ``` + bool ip = 14 [ + (priv.field).cel = { + id: "string.ip", + message: "value must be a valid IP address", + expression: "this == '' || this.isIp()", + }, + (priv.field).cel = { + id: "string.ip_empty", + message: "value is empty, which is not a valid IP address", + expression: "this != ''", + } + ]; + + // `ipv4` specifies that the field value must be a valid IPv4 + // address. If the field value isn't a valid IPv4 address, an error message + // will be generated. + // + // ```proto + // message MyString { + // // value must be a valid IPv4 address + // string value = 1 [(buf.validate.field).string.ipv4 = true]; + // } + // ``` + bool ipv4 = 15 [ + (priv.field).cel = { + id: "string.ipv4", + message: "value must be a valid IPv4 address", + expression: "this == '' || this.isIp(4)", + }, + (priv.field).cel = { + id: "string.ipv4_empty", + message: "value is empty, which is not a valid IPv4 address", + expression: "this != ''", + } + ]; + + // `ipv6` specifies that the field value must be a valid + // IPv6 address, without surrounding square brackets. If the field value is + // not a valid IPv6 address, an error message will be generated. + // + // ```proto + // message MyString { + // // value must be a valid IPv6 address + // string value = 1 [(buf.validate.field).string.ipv6 = true]; + // } + // ``` + bool ipv6 = 16 [ + (priv.field).cel = { + id: "string.ipv6", + message: "value must be a valid IPv6 address", + expression: "this == '' || this.isIp(6)", + }, + (priv.field).cel = { + id: "string.ipv6_empty", + message: "value is empty, which is not a valid IPv6 address", + expression: "this != ''", + } + ]; + + // `uri` specifies that the field value must be a valid, + // absolute URI as defined by [RFC 3986](https://tools.ietf.org/html/rfc3986#section-3). If the field value isn't a valid, + // absolute URI, an error message will be generated. + // + // ```proto + // message MyString { + // // value must be a valid URI + // string value = 1 [(buf.validate.field).string.uri = true]; + // } + // ``` + bool uri = 17 [ + (priv.field).cel = { + id: "string.uri", + message: "value must be a valid URI", + expression: "this == '' || this.isUri()", + }, + (priv.field).cel = { + id: "string.uri_empty", + message: "value is empty, which is not a valid URI", + expression: "this != ''", + } + ]; + + // `uri_ref` specifies that the field value must be a valid URI + // as defined by [RFC 3986](https://tools.ietf.org/html/rfc3986#section-3) and may be either relative or absolute. If the + // field value isn't a valid URI, an error message will be generated. + // + // ```proto + // message MyString { + // // value must be a valid URI + // string value = 1 [(buf.validate.field).string.uri_ref = true]; + // } + // ``` + bool uri_ref = 18 [(priv.field).cel = { + id: "string.uri_ref", + message: "value must be a valid URI", + expression: "this.isUriRef()", + }]; + + // `address` specifies that the field value must be either a valid hostname + // as defined by [RFC 1034](https://tools.ietf.org/html/rfc1034#section-3.5) + // (which doesn't support internationalized domain names or IDNs) or a valid + // IP (v4 or v6). If the field value isn't a valid hostname or IP, an error + // message will be generated. + // + // ```proto + // message MyString { + // // value must be a valid hostname, or ip address + // string value = 1 [(buf.validate.field).string.address = true]; + // } + // ``` + bool address = 21 [ + (priv.field).cel = { + id: "string.address", + message: "value must be a valid hostname, or ip address", + expression: "this == '' || this.isHostname() || this.isIp()", + }, + (priv.field).cel = { + id: "string.address_empty", + message: "value is empty, which is not a valid hostname, or ip address", + expression: "this != ''", + } + ]; + + // `uuid` specifies that the field value must be a valid UUID as defined by + // [RFC 4122](https://tools.ietf.org/html/rfc4122#section-4.1.2). If the + // field value isn't a valid UUID, an error message will be generated. + // + // ```proto + // message MyString { + // // value must be a valid UUID + // string value = 1 [(buf.validate.field).string.uuid = true]; + // } + // ``` + bool uuid = 22 [ + (priv.field).cel = { + id: "string.uuid", + message: "value must be a valid UUID", + expression: "this == '' || this.matches('^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$')", + }, + (priv.field).cel = { + id: "string.uuid_empty", + message: "value is empty, which is not a valid UUID", + expression: "this != ''", + } + ]; + + // `ip_with_prefixlen` specifies that the field value must be a valid IP (v4 or v6) + // address with prefix length. If the field value isn't a valid IP with prefix + // length, an error message will be generated. + // + // + // ```proto + // message MyString { + // // value must be a valid IP with prefix length + // string value = 1 [(buf.validate.field).string.ip_with_prefixlen = true]; + // } + // ``` + bool ip_with_prefixlen = 26 [ + (priv.field).cel = { + id: "string.ip_with_prefixlen", + message: "value must be a valid IP prefix", + expression: "this == '' || this.isIpPrefix()", + }, + (priv.field).cel = { + id: "string.ip_with_prefixlen_empty", + message: "value is empty, which is not a valid IP prefix", + expression: "this != ''", + } + ]; + + // `ipv4_with_prefixlen` specifies that the field value must be a valid + // IPv4 address with prefix. + // If the field value isn't a valid IPv4 address with prefix length, + // an error message will be generated. + // + // ```proto + // message MyString { + // // value must be a valid IPv4 address with prefix length + // string value = 1 [(buf.validate.field).string.ipv4_with_prefixlen = true]; + // } + // ``` + bool ipv4_with_prefixlen = 27 [ + (priv.field).cel = { + id: "string.ipv4_with_prefixlen", + message: "value must be a valid IPv4 address with prefix length", + expression: "this == '' || this.isIpPrefix(4)" + }, + (priv.field).cel = { + id: "string.ipv4_with_prefixlen_empty", + message: "value is empty, which is not a valid IPv4 address with prefix length", + expression: "this != ''" + } + ]; + + // `ipv6_with_prefixlen` specifies that the field value must be a valid + // IPv6 address with prefix length. + // If the field value is not a valid IPv6 address with prefix length, + // an error message will be generated. + // + // ```proto + // message MyString { + // // value must be a valid IPv6 address prefix length + // string value = 1 [(buf.validate.field).string.ipv6_with_prefixlen = true]; + // } + // ``` + bool ipv6_with_prefixlen = 28 [ + (priv.field).cel = { + id: "string.ipv6_with_prefixlen", + message: "value must be a valid IPv6 address with prefix length", + expression: "this == '' || this.isIpPrefix(6)", + }, + (priv.field).cel = { + id: "string.ipv6_with_prefixlen_empty", + message: "value is empty, which is not a valid IPv6 address with prefix length", + expression: "this != ''", + } + ]; + + // `ip_prefix` specifies that the field value must be a valid IP (v4 or v6) prefix. + // If the field value isn't a valid IP prefix, an error message will be + // generated. The prefix must have all zeros for the masked bits of the prefix (e.g., + // `127.0.0.0/16`, not `127.0.0.1/16`). + // + // ```proto + // message MyString { + // // value must be a valid IP prefix + // string value = 1 [(buf.validate.field).string.ip_prefix = true]; + // } + // ``` + bool ip_prefix = 29 [ + (priv.field).cel = { + id: "string.ip_prefix", + message: "value must be a valid IP prefix", + expression: "this == '' || this.isIpPrefix(true)", + }, + (priv.field).cel = { + id: "string.ip_prefix_empty", + message: "value is empty, which is not a valid IP prefix", + expression: "this != ''", + } + ]; + + // `ipv4_prefix` specifies that the field value must be a valid IPv4 + // prefix. If the field value isn't a valid IPv4 prefix, an error message + // will be generated. The prefix must have all zeros for the masked bits of + // the prefix (e.g., `127.0.0.0/16`, not `127.0.0.1/16`). + // + // ```proto + // message MyString { + // // value must be a valid IPv4 prefix + // string value = 1 [(buf.validate.field).string.ipv4_prefix = true]; + // } + // ``` + bool ipv4_prefix = 30 [ + (priv.field).cel = { + id: "string.ipv4_prefix", + message: "value must be a valid IPv4 prefix", + expression: "this == '' || this.isIpPrefix(4, true)" + }, + (priv.field).cel = { + id: "string.ipv4_prefix_empty", + message: "value is empty, which is not a valid IPv4 prefix", + expression: "this != ''" + } + ]; + + // `ipv6_prefix` specifies that the field value must be a valid IPv6 prefix. + // If the field value is not a valid IPv6 prefix, an error message will be + // generated. The prefix must have all zeros for the masked bits of the prefix + // (e.g., `2001:db8::/48`, not `2001:db8::1/48`). + // + // ```proto + // message MyString { + // // value must be a valid IPv6 prefix + // string value = 1 [(buf.validate.field).string.ipv6_prefix = true]; + // } + // ``` + bool ipv6_prefix = 31 [ + (priv.field).cel = { + id: "string.ipv6_prefix", + message: "value must be a valid IPv6 prefix", + expression: "this == '' || this.isIpPrefix(6, true)", + }, + (priv.field).cel = { + id: "string.ipv6_prefix_empty", + message: "value is empty, which is not a valid IPv6 prefix", + expression: "this != ''", + } + ]; + + // `host_and_port` specifies the field value must be a valid host and port + // pair. The host must be a valid hostname or IP address while the port + // must be in the range of 0-65535, inclusive. IPv6 addresses must be delimited + // with square brackets (e.g., `[::1]:1234`). + bool host_and_port = 32 [ + (priv.field).cel = { + id: "string.host_and_port", + message: "value must be a valid host (hostname or IP address) and port pair", + expression: "this == '' || this.isHostAndPort(true)", + }, + (priv.field).cel = { + id: "string.host_and_port_empty", + message: "value is empty, which is not a valid host and port pair", + expression: "this != ''", + } + ]; + + // `well_known_regex` specifies a common well-known pattern + // defined as a regex. If the field value doesn't match the well-known + // regex, an error message will be generated. + // + // ```proto + // message MyString { + // // value must be a valid HTTP header value + // string value = 1 [(buf.validate.field).string.well_known_regex = KNOWN_REGEX_HTTP_HEADER_VALUE]; + // } + // ``` + // + // #### KnownRegex + // + // `well_known_regex` contains some well-known patterns. + // + // | Name | Number | Description | + // |-------------------------------|--------|-------------------------------------------| + // | KNOWN_REGEX_UNSPECIFIED | 0 | | + // | KNOWN_REGEX_HTTP_HEADER_NAME | 1 | HTTP header name as defined by [RFC 7230](https://tools.ietf.org/html/rfc7230#section-3.2) | + // | KNOWN_REGEX_HTTP_HEADER_VALUE | 2 | HTTP header value as defined by [RFC 7230](https://tools.ietf.org/html/rfc7230#section-3.2.4) | + KnownRegex well_known_regex = 24 [ + (priv.field).cel = { + id: "string.well_known_regex.header_name", + message: "value must be a valid HTTP header name", + expression: + "rules.well_known_regex != 1 || this == '' || this.matches(!has(rules.strict) || rules.strict ?" + "'^:?[0-9a-zA-Z!#$%&\\'*+-.^_|~\\x60]+$' :" + "'^[^\\u0000\\u000A\\u000D]+$')", + }, + (priv.field).cel = { + id: "string.well_known_regex.header_name_empty", + message: "value is empty, which is not a valid HTTP header name", + expression: "rules.well_known_regex != 1 || this != ''", + }, + (priv.field).cel = { + id: "string.well_known_regex.header_value", + message: "value must be a valid HTTP header value", + expression: + "rules.well_known_regex != 2 || this.matches(!has(rules.strict) || rules.strict ?" + "'^[^\\u0000-\\u0008\\u000A-\\u001F\\u007F]*$' :" + "'^[^\\u0000\\u000A\\u000D]*$')", + } + ]; + } + + // This applies to regexes `HTTP_HEADER_NAME` and `HTTP_HEADER_VALUE` to + // enable strict header validation. By default, this is true, and HTTP header + // validations are [RFC-compliant](https://tools.ietf.org/html/rfc7230#section-3). Setting to false will enable looser + // validations that only disallow `\r\n\0` characters, which can be used to + // bypass header matching rules. + // + // ```proto + // message MyString { + // // The field `value` must have be a valid HTTP headers, but not enforced with strict rules. + // string value = 1 [(buf.validate.field).string.strict = false]; + // } + // ``` + optional bool strict = 25; +} + +// WellKnownRegex contain some well-known patterns. +enum KnownRegex { + KNOWN_REGEX_UNSPECIFIED = 0; + + // HTTP header name as defined by [RFC 7230](https://tools.ietf.org/html/rfc7230#section-3.2). + KNOWN_REGEX_HTTP_HEADER_NAME = 1; + + // HTTP header value as defined by [RFC 7230](https://tools.ietf.org/html/rfc7230#section-3.2.4). + KNOWN_REGEX_HTTP_HEADER_VALUE = 2; +} + +// BytesRules describe the constraints applied to `bytes` values. These rules +// may also be applied to the `google.protobuf.BytesValue` Well-Known-Type. +message BytesRules { + // `const` requires the field value to exactly match the specified bytes + // value. If the field value doesn't match, an error message is generated. + // + // ```proto + // message MyBytes { + // // value must be "\x01\x02\x03\x04" + // bytes value = 1 [(buf.validate.field).bytes.const = "\x01\x02\x03\x04"]; + // } + // ``` + optional bytes const = 1 [(priv.field).cel = { + id: "bytes.const", + expression: "this != rules.const ? 'value must be %x'.format([rules.const]) : ''" + }]; + + // `len` requires the field value to have the specified length in bytes. + // If the field value doesn't match, an error message is generated. + // + // ```proto + // message MyBytes { + // // value length must be 4 bytes. + // optional bytes value = 1 [(buf.validate.field).bytes.len = 4]; + // } + // ``` + optional uint64 len = 13 [(priv.field).cel = { + id: "bytes.len", + expression: "uint(this.size()) != rules.len ? 'value length must be %s bytes'.format([rules.len]) : ''" + }]; + + // `min_len` requires the field value to have at least the specified minimum + // length in bytes. + // If the field value doesn't meet the requirement, an error message is generated. + // + // ```proto + // message MyBytes { + // // value length must be at least 2 bytes. + // optional bytes value = 1 [(buf.validate.field).bytes.min_len = 2]; + // } + // ``` + optional uint64 min_len = 2 [(priv.field).cel = { + id: "bytes.min_len", + expression: "uint(this.size()) < rules.min_len ? 'value length must be at least %s bytes'.format([rules.min_len]) : ''" + }]; + + // `max_len` requires the field value to have at most the specified maximum + // length in bytes. + // If the field value exceeds the requirement, an error message is generated. + // + // ```proto + // message MyBytes { + // // value must be at most 6 bytes. + // optional bytes value = 1 [(buf.validate.field).bytes.max_len = 6]; + // } + // ``` + optional uint64 max_len = 3 [(priv.field).cel = { + id: "bytes.max_len", + expression: "uint(this.size()) > rules.max_len ? 'value must be at most %s bytes'.format([rules.max_len]) : ''" + }]; + + // `pattern` requires the field value to match the specified regular + // expression ([RE2 syntax](https://github.com/google/re2/wiki/Syntax)). + // The value of the field must be valid UTF-8 or validation will fail with a + // runtime error. + // If the field value doesn't match the pattern, an error message is generated. + // + // ```proto + // message MyBytes { + // // value must match regex pattern "^[a-zA-Z0-9]+$". + // optional bytes value = 1 [(buf.validate.field).bytes.pattern = "^[a-zA-Z0-9]+$"]; + // } + // ``` + optional string pattern = 4 [(priv.field).cel = { + id: "bytes.pattern", + expression: "!string(this).matches(rules.pattern) ? 'value must match regex pattern `%s`'.format([rules.pattern]) : ''" + }]; + + // `prefix` requires the field value to have the specified bytes at the + // beginning of the string. + // If the field value doesn't meet the requirement, an error message is generated. + // + // ```proto + // message MyBytes { + // // value does not have prefix \x01\x02 + // optional bytes value = 1 [(buf.validate.field).bytes.prefix = "\x01\x02"]; + // } + // ``` + optional bytes prefix = 5 [(priv.field).cel = { + id: "bytes.prefix", + expression: "!this.startsWith(rules.prefix) ? 'value does not have prefix %x'.format([rules.prefix]) : ''" + }]; + + // `suffix` requires the field value to have the specified bytes at the end + // of the string. + // If the field value doesn't meet the requirement, an error message is generated. + // + // ```proto + // message MyBytes { + // // value does not have suffix \x03\x04 + // optional bytes value = 1 [(buf.validate.field).bytes.suffix = "\x03\x04"]; + // } + // ``` + optional bytes suffix = 6 [(priv.field).cel = { + id: "bytes.suffix", + expression: "!this.endsWith(rules.suffix) ? 'value does not have suffix %x'.format([rules.suffix]) : ''" + }]; + + // `contains` requires the field value to have the specified bytes anywhere in + // the string. + // If the field value doesn't meet the requirement, an error message is generated. + // + // ```protobuf + // message MyBytes { + // // value does not contain \x02\x03 + // optional bytes value = 1 [(buf.validate.field).bytes.contains = "\x02\x03"]; + // } + // ``` + optional bytes contains = 7 [(priv.field).cel = { + id: "bytes.contains", + expression: "!this.contains(rules.contains) ? 'value does not contain %x'.format([rules.contains]) : ''" + }]; + + // `in` requires the field value to be equal to one of the specified + // values. If the field value doesn't match any of the specified values, an + // error message is generated. + // + // ```protobuf + // message MyBytes { + // // value must in ["\x01\x02", "\x02\x03", "\x03\x04"] + // optional bytes value = 1 [(buf.validate.field).bytes.in = {"\x01\x02", "\x02\x03", "\x03\x04"}]; + // } + // ``` + repeated bytes in = 8 [(priv.field).cel = { + id: "bytes.in", + expression: "dyn(rules)['in'].size() > 0 && !(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''" + }]; + + // `not_in` requires the field value to be not equal to any of the specified + // values. + // If the field value matches any of the specified values, an error message is + // generated. + // + // ```proto + // message MyBytes { + // // value must not in ["\x01\x02", "\x02\x03", "\x03\x04"] + // optional bytes value = 1 [(buf.validate.field).bytes.not_in = {"\x01\x02", "\x02\x03", "\x03\x04"}]; + // } + // ``` + repeated bytes not_in = 9 [(priv.field).cel = { + id: "bytes.not_in", + expression: "this in rules.not_in ? 'value must not be in list %s'.format([rules.not_in]) : ''" + }]; + + // WellKnown rules provide advanced constraints against common byte + // patterns + oneof well_known { + // `ip` ensures that the field `value` is a valid IP address (v4 or v6) in byte format. + // If the field value doesn't meet this constraint, an error message is generated. + // + // ```proto + // message MyBytes { + // // value must be a valid IP address + // optional bytes value = 1 [(buf.validate.field).bytes.ip = true]; + // } + // ``` + bool ip = 10 [ + (priv.field).cel = { + id: "bytes.ip", + message: "value must be a valid IP address", + expression: "this.size() == 0 || this.size() == 4 || this.size() == 16", + }, + (priv.field).cel = { + id: "bytes.ip_empty", + message: "value is empty, which is not a valid IP address", + expression: "this.size() != 0", + } + ]; + + // `ipv4` ensures that the field `value` is a valid IPv4 address in byte format. + // If the field value doesn't meet this constraint, an error message is generated. + // + // ```proto + // message MyBytes { + // // value must be a valid IPv4 address + // optional bytes value = 1 [(buf.validate.field).bytes.ipv4 = true]; + // } + // ``` + bool ipv4 = 11 [ + (priv.field).cel = { + id: "bytes.ipv4", + message: "value must be a valid IPv4 address", + expression: "this.size() == 0 || this.size() == 4", + }, + (priv.field).cel = { + id: "bytes.ipv4_empty", + message: "value is empty, which is not a valid IPv4 address", + expression: "this.size() != 0", + } + ]; + + // `ipv6` ensures that the field `value` is a valid IPv6 address in byte format. + // If the field value doesn't meet this constraint, an error message is generated. + // ```proto + // message MyBytes { + // // value must be a valid IPv6 address + // optional bytes value = 1 [(buf.validate.field).bytes.ipv6 = true]; + // } + // ``` + bool ipv6 = 12 [ + (priv.field).cel = { + id: "bytes.ipv6", + message: "value must be a valid IPv6 address", + expression: "this.size() == 0 || this.size() == 16" + }, + (priv.field).cel = { + id: "bytes.ipv6_empty", + message: "value is empty, which is not a valid IPv6 address", + expression: "this.size() != 0", + } + ]; + } +} + +// EnumRules describe the constraints applied to `enum` values. +message EnumRules { + // `const` requires the field value to exactly match the specified enum value. + // If the field value doesn't match, an error message is generated. + // + // ```proto + // enum MyEnum { + // MY_ENUM_UNSPECIFIED = 0; + // MY_ENUM_VALUE1 = 1; + // MY_ENUM_VALUE2 = 2; + // } + // + // message MyMessage { + // // The field `value` must be exactly MY_ENUM_VALUE1. + // MyEnum value = 1 [(buf.validate.field).enum.const = 1]; + // } + // ``` + optional int32 const = 1 [(priv.field).cel = { + id: "enum.const", + expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''", + }]; + + // `defined_only` requires the field value to be one of the defined values for + // this enum, failing on any undefined value. + // + // ```proto + // enum MyEnum { + // MY_ENUM_UNSPECIFIED = 0; + // MY_ENUM_VALUE1 = 1; + // MY_ENUM_VALUE2 = 2; + // } + // + // message MyMessage { + // // The field `value` must be a defined value of MyEnum. + // MyEnum value = 1 [(buf.validate.field).enum.defined_only = true]; + // } + // ``` + optional bool defined_only = 2; + + // `in` requires the field value to be equal to one of the + //specified enum values. If the field value doesn't match any of the + //specified values, an error message is generated. + // + // ```proto + // enum MyEnum { + // MY_ENUM_UNSPECIFIED = 0; + // MY_ENUM_VALUE1 = 1; + // MY_ENUM_VALUE2 = 2; + // } + // + // message MyMessage { + // // The field `value` must be equal to one of the specified values. + // MyEnum value = 1 [(buf.validate.field).enum = { in: [1, 2]}]; + // } + // ``` + repeated int32 in = 3 [(priv.field).cel = { + id: "enum.in", + expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''", + }]; + + // `not_in` requires the field value to be not equal to any of the + //specified enum values. If the field value matches one of the specified + // values, an error message is generated. + // + // ```proto + // enum MyEnum { + // MY_ENUM_UNSPECIFIED = 0; + // MY_ENUM_VALUE1 = 1; + // MY_ENUM_VALUE2 = 2; + // } + // + // message MyMessage { + // // The field `value` must not be equal to any of the specified values. + // MyEnum value = 1 [(buf.validate.field).enum = { not_in: [1, 2]}]; + // } + // ``` + repeated int32 not_in = 4 [(priv.field).cel = { + id: "enum.not_in", + expression: "this in rules.not_in ? 'value must not be in list %s'.format([rules.not_in]) : ''", + }]; +} + +// RepeatedRules describe the constraints applied to `repeated` values. +message RepeatedRules { + // `min_items` requires that this field must contain at least the specified + // minimum number of items. + // + // Note that `min_items = 1` is equivalent to setting a field as `required`. + // + // ```proto + // message MyRepeated { + // // value must contain at least 2 items + // repeated string value = 1 [(buf.validate.field).repeated.min_items = 2]; + // } + // ``` + optional uint64 min_items = 1 [(priv.field).cel = { + id: "repeated.min_items" + expression: "uint(this.size()) < rules.min_items ? 'value must contain at least %d item(s)'.format([rules.min_items]) : ''" + }]; + + // `max_items` denotes that this field must not exceed a + // certain number of items as the upper limit. If the field contains more + // items than specified, an error message will be generated, requiring the + // field to maintain no more than the specified number of items. + // + // ```proto + // message MyRepeated { + // // value must contain no more than 3 item(s) + // repeated string value = 1 [(buf.validate.field).repeated.max_items = 3]; + // } + // ``` + optional uint64 max_items = 2 [(priv.field).cel = { + id: "repeated.max_items" + expression: "uint(this.size()) > rules.max_items ? 'value must contain no more than %s item(s)'.format([rules.max_items]) : ''" + }]; + + // `unique` indicates that all elements in this field must + // be unique. This constraint is strictly applicable to scalar and enum + // types, with message types not being supported. + // + // ```proto + // message MyRepeated { + // // repeated value must contain unique items + // repeated string value = 1 [(buf.validate.field).repeated.unique = true]; + // } + // ``` + optional bool unique = 3 [(priv.field).cel = { + id: "repeated.unique" + message: "repeated value must contain unique items" + expression: "this.unique()" + }]; + + // `items` details the constraints to be applied to each item + // in the field. Even for repeated message fields, validation is executed + // against each item unless skip is explicitly specified. + // + // ```proto + // message MyRepeated { + // // The items in the field `value` must follow the specified constraints. + // repeated string value = 1 [(buf.validate.field).repeated.items = { + // string: { + // min_len: 3 + // max_len: 10 + // } + // }]; + // } + // ``` + optional FieldConstraints items = 4; +} + +// MapRules describe the constraints applied to `map` values. +message MapRules { + //Specifies the minimum number of key-value pairs allowed. If the field has + // fewer key-value pairs than specified, an error message is generated. + // + // ```proto + // message MyMap { + // // The field `value` must have at least 2 key-value pairs. + // map value = 1 [(buf.validate.field).map.min_pairs = 2]; + // } + // ``` + optional uint64 min_pairs = 1 [(priv.field).cel = { + id: "map.min_pairs" + expression: "uint(this.size()) < rules.min_pairs ? 'map must be at least %d entries'.format([rules.min_pairs]) : ''" + }]; + + //Specifies the maximum number of key-value pairs allowed. If the field has + // more key-value pairs than specified, an error message is generated. + // + // ```proto + // message MyMap { + // // The field `value` must have at most 3 key-value pairs. + // map value = 1 [(buf.validate.field).map.max_pairs = 3]; + // } + // ``` + optional uint64 max_pairs = 2 [(priv.field).cel = { + id: "map.max_pairs" + expression: "uint(this.size()) > rules.max_pairs ? 'map must be at most %d entries'.format([rules.max_pairs]) : ''" + }]; + + //Specifies the constraints to be applied to each key in the field. + // + // ```proto + // message MyMap { + // // The keys in the field `value` must follow the specified constraints. + // map value = 1 [(buf.validate.field).map.keys = { + // string: { + // min_len: 3 + // max_len: 10 + // } + // }]; + // } + // ``` + optional FieldConstraints keys = 4; + + //Specifies the constraints to be applied to the value of each key in the + // field. Message values will still have their validations evaluated unless + //skip is specified here. + // + // ```proto + // message MyMap { + // // The values in the field `value` must follow the specified constraints. + // map value = 1 [(buf.validate.field).map.values = { + // string: { + // min_len: 5 + // max_len: 20 + // } + // }]; + // } + // ``` + optional FieldConstraints values = 5; +} + +// AnyRules describe constraints applied exclusively to the `google.protobuf.Any` well-known type. +message AnyRules { + // `in` requires the field's `type_url` to be equal to one of the + //specified values. If it doesn't match any of the specified values, an error + // message is generated. + // + // ```proto + // message MyAny { + // // The `value` field must have a `type_url` equal to one of the specified values. + // google.protobuf.Any value = 1 [(buf.validate.field).any.in = ["type.googleapis.com/MyType1", "type.googleapis.com/MyType2"]]; + // } + // ``` + repeated string in = 2; + + // requires the field's type_url to be not equal to any of the specified values. If it matches any of the specified values, an error message is generated. + // + // ```proto + // message MyAny { + // // The field `value` must not have a `type_url` equal to any of the specified values. + // google.protobuf.Any value = 1 [(buf.validate.field).any.not_in = ["type.googleapis.com/ForbiddenType1", "type.googleapis.com/ForbiddenType2"]]; + // } + // ``` + repeated string not_in = 3; +} + +// DurationRules describe the constraints applied exclusively to the `google.protobuf.Duration` well-known type. +message DurationRules { + // `const` dictates that the field must match the specified value of the `google.protobuf.Duration` type exactly. + // If the field's value deviates from the specified value, an error message + // will be generated. + // + // ```proto + // message MyDuration { + // // value must equal 5s + // google.protobuf.Duration value = 1 [(buf.validate.field).duration.const = "5s"]; + // } + // ``` + optional google.protobuf.Duration const = 2 [(priv.field).cel = { + id: "duration.const", + expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''", + }]; + oneof less_than { + // `lt` stipulates that the field must be less than the specified value of the `google.protobuf.Duration` type, + // exclusive. If the field's value is greater than or equal to the specified + // value, an error message will be generated. + // + // ```proto + // message MyDuration { + // // value must be less than 5s + // google.protobuf.Duration value = 1 [(buf.validate.field).duration.lt = "5s"]; + // } + // ``` + google.protobuf.Duration lt = 3 [(priv.field).cel = { + id: "duration.lt", + expression: + "!has(rules.gte) && !has(rules.gt) && this >= rules.lt" + "? 'value must be less than %s'.format([rules.lt]) : ''" + }]; + + // `lte` indicates that the field must be less than or equal to the specified + // value of the `google.protobuf.Duration` type, inclusive. If the field's value is greater than the specified value, + // an error message will be generated. + // + // ```proto + // message MyDuration { + // // value must be less than or equal to 10s + // google.protobuf.Duration value = 1 [(buf.validate.field).duration.lte = "10s"]; + // } + // ``` + google.protobuf.Duration lte = 4 [(priv.field).cel = { + id: "duration.lte", + expression: + "!has(rules.gte) && !has(rules.gt) && this > rules.lte" + "? 'value must be less than or equal to %s'.format([rules.lte]) : ''" + }]; + } + oneof greater_than { + // `gt` requires the duration field value to be greater than the specified + // value (exclusive). If the value of `gt` is larger than a specified `lt` + // or `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MyDuration { + // // duration must be greater than 5s [duration.gt] + // google.protobuf.Duration value = 1 [(buf.validate.field).duration.gt = { seconds: 5 }]; + // + // // duration must be greater than 5s and less than 10s [duration.gt_lt] + // google.protobuf.Duration another_value = 2 [(buf.validate.field).duration = { gt: { seconds: 5 }, lt: { seconds: 10 } }]; + // + // // duration must be greater than 10s or less than 5s [duration.gt_lt_exclusive] + // google.protobuf.Duration other_value = 3 [(buf.validate.field).duration = { gt: { seconds: 10 }, lt: { seconds: 5 } }]; + // } + // ``` + google.protobuf.Duration gt = 5 [ + (priv.field).cel = { + id: "duration.gt", + expression: + "!has(rules.lt) && !has(rules.lte) && this <= rules.gt" + "? 'value must be greater than %s'.format([rules.gt]) : ''" + }, + (priv.field).cel = { + id: "duration.gt_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gt && (this >= rules.lt || this <= rules.gt)" + "? 'value must be greater than %s and less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "duration.gt_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gt && (rules.lt <= this && this <= rules.gt)" + "? 'value must be greater than %s or less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "duration.gt_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gt && (this > rules.lte || this <= rules.gt)" + "? 'value must be greater than %s and less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "duration.gt_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gt && (rules.lte < this && this <= rules.gt)" + "? 'value must be greater than %s or less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + } + ]; + + // `gte` requires the duration field value to be greater than or equal to the + // specified value (exclusive). If the value of `gte` is larger than a + // specified `lt` or `lte`, the range is reversed, and the field value must + // be outside the specified range. If the field value doesn't meet the + // required conditions, an error message is generated. + // + // ```proto + // message MyDuration { + // // duration must be greater than or equal to 5s [duration.gte] + // google.protobuf.Duration value = 1 [(buf.validate.field).duration.gte = { seconds: 5 }]; + // + // // duration must be greater than or equal to 5s and less than 10s [duration.gte_lt] + // google.protobuf.Duration another_value = 2 [(buf.validate.field).duration = { gte: { seconds: 5 }, lt: { seconds: 10 } }]; + // + // // duration must be greater than or equal to 10s or less than 5s [duration.gte_lt_exclusive] + // google.protobuf.Duration other_value = 3 [(buf.validate.field).duration = { gte: { seconds: 10 }, lt: { seconds: 5 } }]; + // } + // ``` + google.protobuf.Duration gte = 6 [ + (priv.field).cel = { + id: "duration.gte", + expression: + "!has(rules.lt) && !has(rules.lte) && this < rules.gte" + "? 'value must be greater than or equal to %s'.format([rules.gte]) : ''" + }, + (priv.field).cel = { + id: "duration.gte_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gte && (this >= rules.lt || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "duration.gte_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gte && (rules.lt <= this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "duration.gte_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gte && (this > rules.lte || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "duration.gte_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gte && (rules.lte < this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + } + ]; + } + + // `in` asserts that the field must be equal to one of the specified values of the `google.protobuf.Duration` type. + // If the field's value doesn't correspond to any of the specified values, + // an error message will be generated. + // + // ```proto + // message MyDuration { + // // value must be in list [1s, 2s, 3s] + // google.protobuf.Duration value = 1 [(buf.validate.field).duration.in = ["1s", "2s", "3s"]]; + // } + // ``` + repeated google.protobuf.Duration in = 7 [(priv.field).cel = { + id: "duration.in", + expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''", + }]; + + // `not_in` denotes that the field must not be equal to + // any of the specified values of the `google.protobuf.Duration` type. + // If the field's value matches any of these values, an error message will be + // generated. + // + // ```proto + // message MyDuration { + // // value must not be in list [1s, 2s, 3s] + // google.protobuf.Duration value = 1 [(buf.validate.field).duration.not_in = ["1s", "2s", "3s"]]; + // } + // ``` + repeated google.protobuf.Duration not_in = 8 [(priv.field).cel = { + id: "duration.not_in", + expression: "this in rules.not_in ? 'value must not be in list %s'.format([rules.not_in]) : ''", + }]; +} + +// TimestampRules describe the constraints applied exclusively to the `google.protobuf.Timestamp` well-known type. +message TimestampRules { + // `const` dictates that this field, of the `google.protobuf.Timestamp` type, must exactly match the specified value. If the field value doesn't correspond to the specified timestamp, an error message will be generated. + // + // ```proto + // message MyTimestamp { + // // value must equal 2023-05-03T10:00:00Z + // google.protobuf.Timestamp created_at = 1 [(buf.validate.field).timestamp.const = {seconds: 1727998800}]; + // } + // ``` + optional google.protobuf.Timestamp const = 2 [(priv.field).cel = { + id: "timestamp.const", + expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''", + }]; + oneof less_than { + // requires the duration field value to be less than the specified value (field < value). If the field value doesn't meet the required conditions, an error message is generated. + // + // ```proto + // message MyDuration { + // // duration must be less than 'P3D' [duration.lt] + // google.protobuf.Duration value = 1 [(buf.validate.field).duration.lt = { seconds: 259200 }]; + // } + // ``` + google.protobuf.Timestamp lt = 3 [(priv.field).cel = { + id: "timestamp.lt", + expression: + "!has(rules.gte) && !has(rules.gt) && this >= rules.lt" + "? 'value must be less than %s'.format([rules.lt]) : ''" + }]; + + // requires the timestamp field value to be less than or equal to the specified value (field <= value). If the field value doesn't meet the required conditions, an error message is generated. + // + // ```proto + // message MyTimestamp { + // // timestamp must be less than or equal to '2023-05-14T00:00:00Z' [timestamp.lte] + // google.protobuf.Timestamp value = 1 [(buf.validate.field).timestamp.lte = { seconds: 1678867200 }]; + // } + // ``` + google.protobuf.Timestamp lte = 4 [(priv.field).cel = { + id: "timestamp.lte", + expression: + "!has(rules.gte) && !has(rules.gt) && this > rules.lte" + "? 'value must be less than or equal to %s'.format([rules.lte]) : ''" + }]; + + // `lt_now` specifies that this field, of the `google.protobuf.Timestamp` type, must be less than the current time. `lt_now` can only be used with the `within` rule. + // + // ```proto + // message MyTimestamp { + // // value must be less than now + // google.protobuf.Timestamp created_at = 1 [(buf.validate.field).timestamp.lt_now = true]; + // } + // ``` + bool lt_now = 7 [(priv.field).cel = { + id: "timestamp.lt_now", + expression: "this > now ? 'value must be less than now' : ''" + }]; + } + oneof greater_than { + // `gt` requires the timestamp field value to be greater than the specified + // value (exclusive). If the value of `gt` is larger than a specified `lt` + // or `lte`, the range is reversed, and the field value must be outside the + // specified range. If the field value doesn't meet the required conditions, + // an error message is generated. + // + // ```proto + // message MyTimestamp { + // // timestamp must be greater than '2023-01-01T00:00:00Z' [timestamp.gt] + // google.protobuf.Timestamp value = 1 [(buf.validate.field).timestamp.gt = { seconds: 1672444800 }]; + // + // // timestamp must be greater than '2023-01-01T00:00:00Z' and less than '2023-01-02T00:00:00Z' [timestamp.gt_lt] + // google.protobuf.Timestamp another_value = 2 [(buf.validate.field).timestamp = { gt: { seconds: 1672444800 }, lt: { seconds: 1672531200 } }]; + // + // // timestamp must be greater than '2023-01-02T00:00:00Z' or less than '2023-01-01T00:00:00Z' [timestamp.gt_lt_exclusive] + // google.protobuf.Timestamp other_value = 3 [(buf.validate.field).timestamp = { gt: { seconds: 1672531200 }, lt: { seconds: 1672444800 } }]; + // } + // ``` + google.protobuf.Timestamp gt = 5 [ + (priv.field).cel = { + id: "timestamp.gt", + expression: + "!has(rules.lt) && !has(rules.lte) && this <= rules.gt" + "? 'value must be greater than %s'.format([rules.gt]) : ''" + }, + (priv.field).cel = { + id: "timestamp.gt_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gt && (this >= rules.lt || this <= rules.gt)" + "? 'value must be greater than %s and less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "timestamp.gt_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gt && (rules.lt <= this && this <= rules.gt)" + "? 'value must be greater than %s or less than %s'.format([rules.gt, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "timestamp.gt_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gt && (this > rules.lte || this <= rules.gt)" + "? 'value must be greater than %s and less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "timestamp.gt_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gt && (rules.lte < this && this <= rules.gt)" + "? 'value must be greater than %s or less than or equal to %s'.format([rules.gt, rules.lte]) : ''" + } + ]; + + // `gte` requires the timestamp field value to be greater than or equal to the + // specified value (exclusive). If the value of `gte` is larger than a + // specified `lt` or `lte`, the range is reversed, and the field value + // must be outside the specified range. If the field value doesn't meet + // the required conditions, an error message is generated. + // + // ```proto + // message MyTimestamp { + // // timestamp must be greater than or equal to '2023-01-01T00:00:00Z' [timestamp.gte] + // google.protobuf.Timestamp value = 1 [(buf.validate.field).timestamp.gte = { seconds: 1672444800 }]; + // + // // timestamp must be greater than or equal to '2023-01-01T00:00:00Z' and less than '2023-01-02T00:00:00Z' [timestamp.gte_lt] + // google.protobuf.Timestamp another_value = 2 [(buf.validate.field).timestamp = { gte: { seconds: 1672444800 }, lt: { seconds: 1672531200 } }]; + // + // // timestamp must be greater than or equal to '2023-01-02T00:00:00Z' or less than '2023-01-01T00:00:00Z' [timestamp.gte_lt_exclusive] + // google.protobuf.Timestamp other_value = 3 [(buf.validate.field).timestamp = { gte: { seconds: 1672531200 }, lt: { seconds: 1672444800 } }]; + // } + // ``` + google.protobuf.Timestamp gte = 6 [ + (priv.field).cel = { + id: "timestamp.gte", + expression: + "!has(rules.lt) && !has(rules.lte) && this < rules.gte" + "? 'value must be greater than or equal to %s'.format([rules.gte]) : ''" + }, + (priv.field).cel = { + id: "timestamp.gte_lt", + expression: + "has(rules.lt) && rules.lt >= rules.gte && (this >= rules.lt || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "timestamp.gte_lt_exclusive", + expression: + "has(rules.lt) && rules.lt < rules.gte && (rules.lt <= this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than %s'.format([rules.gte, rules.lt]) : ''" + }, + (priv.field).cel = { + id: "timestamp.gte_lte", + expression: + "has(rules.lte) && rules.lte >= rules.gte && (this > rules.lte || this < rules.gte)" + "? 'value must be greater than or equal to %s and less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + }, + (priv.field).cel = { + id: "timestamp.gte_lte_exclusive", + expression: + "has(rules.lte) && rules.lte < rules.gte && (rules.lte < this && this < rules.gte)" + "? 'value must be greater than or equal to %s or less than or equal to %s'.format([rules.gte, rules.lte]) : ''" + } + ]; + + // `gt_now` specifies that this field, of the `google.protobuf.Timestamp` type, must be greater than the current time. `gt_now` can only be used with the `within` rule. + // + // ```proto + // message MyTimestamp { + // // value must be greater than now + // google.protobuf.Timestamp created_at = 1 [(buf.validate.field).timestamp.gt_now = true]; + // } + // ``` + bool gt_now = 8 [(priv.field).cel = { + id: "timestamp.gt_now", + expression: "this < now ? 'value must be greater than now' : ''" + }]; + } + + // `within` specifies that this field, of the `google.protobuf.Timestamp` type, must be within the specified duration of the current time. If the field value isn't within the duration, an error message is generated. + // + // ```proto + // message MyTimestamp { + // // value must be within 1 hour of now + // google.protobuf.Timestamp created_at = 1 [(buf.validate.field).timestamp.within = {seconds: 3600}]; + // } + // ``` + optional google.protobuf.Duration within = 9 [(priv.field).cel = { + id: "timestamp.within", + expression: "this < now-rules.within || this > now+rules.within ? 'value must be within %s of now'.format([rules.within]) : ''" + }]; +} diff --git a/documents/api/block/stream/output/consensus_service.md b/documents/api/block/stream/output/consensus_service.md index 09a86109..52eeec87 100644 --- a/documents/api/block/stream/output/consensus_service.md +++ b/documents/api/block/stream/output/consensus_service.md @@ -22,7 +22,11 @@ by the `Consensus` service. ### Topic Running Hash Calculation Submitted messages include a topic running hash. This value has changed over time, with the known versions detailed in the `RunningHashVersion` -enumeration. +enumeration. The running hash version SHALL NOT be transmitted in the +Block Stream, however, as it is a fixed value that can only be changed +with a new release of consensus node software following a HIP to update +the specification, so repeating that fixed value in the block stream is +wasteful and unnecessary. ### Keywords The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", diff --git a/documents/api/services/address_book_service.md b/documents/api/services/address_book_service.md new file mode 100644 index 00000000..64ca7799 --- /dev/null +++ b/documents/api/services/address_book_service.md @@ -0,0 +1,139 @@ +## Table of Contents + +- [address_book_service.proto](#address_book_service-proto) + - [AddressBookService](#proto-AddressBookService) + + + + + +

Top

+ +## address_book_service.proto +# Address Book Service API +GRPC service definitions for the Hedera Address Book Service (HABS). + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + + + + + + + +### AddressBookService +The Address Book service provides the ability for Hedera network node +administrators to add, update, and remove consensus nodes. This addition, +update, or removal of a consensus node requires governing council approval, +but each node operator may update their own operational attributes without +additional approval, reducing overhead for routine operations. + +Most operations are `privileged operations` and require governing council +approval. + +### For a node creation transaction. +- The node operator SHALL create a `createNode` transaction. + - The node operator MUST sign this transaction with the active `Key` for + the account to be assigned as the "node account". + - The node operator MUST sign this transaction with the `Key` + set as the `admin_key` for the new `Node`. + - The node operator SHALL deliver the signed transaction to the Hedera + council representative. + - The Hedera council representative SHALL arrange for council members to + review and sign the transaction. + - Once sufficient council members have signed the transaction, the + Hedera council representative SHALL submit the transaction to the + network. +- Upon receipt of a valid and signed node creation transaction the network + software SHALL + - Validate the threshold signature for the Hedera governing council + - Validate the signature of the `Key` provided as the new `admin_key` + for the `Node`. + - Validate the signature of the active `Key` for the account to be + assigned as the "node account". + - Create the new node in state, this new node SHALL NOT be active in the + network at this time. + - When executing the next `freeze` transaction with `freeze_type` set to + `PREPARE_UPGRADE`, update network configuration and bring the + new node to an active status within the network. The node to be added + SHALL be active in the network following this upgrade. + +### For a node deletion transaction. +- The node operator or Hedera council representative SHALL create a + `deleteNode` transaction. + - If the node operator creates the transaction + - The node operator MUST sign this transaction with the `Key` + set as the `admin_key` for the existing `Node`. + - The node operator SHALL deliver the signed transaction to the Hedera + council representative. + - The Hedera council representative SHALL arrange for council members to + review and sign the transaction. + - Once sufficient council members have signed the transaction, the + Hedera council representative SHALL submit the transaction to the + network. +- Upon receipt of a valid and signed node deletion transaction the network + software SHALL + - Validate the threshold signature for the Hedera governing council + - Remove the existing node from network state. The node SHALL still + be active in the network at this time. + - When executing the next `freeze` transaction with `freeze_type` set to + `PREPARE_UPGRADE`, update network configuration and remove the + node to be deleted from the network. The node to be deleted SHALL NOT + be active in the network following this upgrade. + +### For a node update transaction. +- The node operator SHALL create an `updateNode` transaction. + - The node operator MUST sign this transaction with the `Key` + assigned as the current `admin_key`. + - If the transaction changes the value of the `admin_key` for the node, + - The node operator MUST sign this transaction with the `Key` + assigned as the new `admin_key`. + - If the transaction changes the value of the "node account", + - The node operator MUST sign this transaction with the + active `Key` for the account to be assigned as the new + "node account". + - The node operator MUST _also_ sign this transaction with the + active `Key` for the account _currently_ assigned as the + "node account". + - The node operator SHALL submit the transaction to the + network. Hedera council approval SHALL NOT be sought for this + transaction +- Upon receipt of a valid and signed node update transaction the network + software SHALL + - Validate the signature of the `Key` currently assigned as the + `admin_key` for the `Node`. + - If the transaction modifies the value of the `admin_key`, + - Validate the signature of the `Key` provided as the new `admin_key` + for the `Node`. + - If the transaction modifies the value of the "node account", + - Validate the signature of the active `Key` for the account + currently assigned as the "node account". + - Validate the signature of the `Key` for the account to be + assigned as the _new_ "node account". + - Modify the node information held in network state with the changes + requested in the update transaction. The node changes SHALL NOT be + applied to network configuration, and SHALL NOT affect network + operation at this time. + - When executing the next `freeze` transaction with `freeze_type` set to + `PREPARE_UPGRADE`, update network configuration according to the + modified information in network state. The requested changes SHALL + affect network operation following this upgrade. + +| Method Name | Request Type | Response Type | Description | +| ----------- | ------------ | ------------- | ------------| +| createNode | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | A transaction to create a new consensus node in the network address book.

This transaction, once complete, SHALL add a new consensus node to the network state.
The new consensus node SHALL remain in state, but SHALL NOT participate in network consensus until the network updates the network configuration.

Hedera governing council authorization is REQUIRED for this transaction. | +| deleteNode | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | A transaction to remove a consensus node from the network address book.

This transaction, once complete, SHALL remove the identified consensus node from the network state.

Hedera governing council authorization is REQUIRED for this transaction. | +| updateNode | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | A transaction to update an existing consensus node from the network address book.

This transaction, once complete, SHALL modify the identified consensus node state as requested.

This transaction MUST be authorized by the node operator. | + + + + + diff --git a/documents/api/services/basic_types.md b/documents/api/services/basic_types.md new file mode 100644 index 00000000..ab51131e --- /dev/null +++ b/documents/api/services/basic_types.md @@ -0,0 +1,1449 @@ +## Table of Contents + +- [basic_types.proto](#basic_types-proto) + - [AccountAmount](#proto-AccountAmount) + - [AccountID](#proto-AccountID) + - [ContractID](#proto-ContractID) + - [CurrentAndNextFeeSchedule](#proto-CurrentAndNextFeeSchedule) + - [FeeComponents](#proto-FeeComponents) + - [FeeData](#proto-FeeData) + - [FeeSchedule](#proto-FeeSchedule) + - [FileID](#proto-FileID) + - [Fraction](#proto-Fraction) + - [Key](#proto-Key) + - [KeyList](#proto-KeyList) + - [NftID](#proto-NftID) + - [NftTransfer](#proto-NftTransfer) + - [NodeAddress](#proto-NodeAddress) + - [NodeAddressBook](#proto-NodeAddressBook) + - [PendingAirdropId](#proto-PendingAirdropId) + - [PendingAirdropValue](#proto-PendingAirdropValue) + - [RealmID](#proto-RealmID) + - [ScheduleID](#proto-ScheduleID) + - [SemanticVersion](#proto-SemanticVersion) + - [ServiceEndpoint](#proto-ServiceEndpoint) + - [ServicesConfigurationList](#proto-ServicesConfigurationList) + - [Setting](#proto-Setting) + - [ShardID](#proto-ShardID) + - [Signature](#proto-Signature) + - [SignatureList](#proto-SignatureList) + - [SignatureMap](#proto-SignatureMap) + - [SignaturePair](#proto-SignaturePair) + - [StakingInfo](#proto-StakingInfo) + - [ThresholdKey](#proto-ThresholdKey) + - [ThresholdSignature](#proto-ThresholdSignature) + - [TokenAssociation](#proto-TokenAssociation) + - [TokenBalance](#proto-TokenBalance) + - [TokenBalances](#proto-TokenBalances) + - [TokenID](#proto-TokenID) + - [TokenRelationship](#proto-TokenRelationship) + - [TokenTransferList](#proto-TokenTransferList) + - [TopicID](#proto-TopicID) + - [TransactionFeeSchedule](#proto-TransactionFeeSchedule) + - [TransactionID](#proto-TransactionID) + - [TransferList](#proto-TransferList) + + - [BlockHashAlgorithm](#proto-BlockHashAlgorithm) + - [HederaFunctionality](#proto-HederaFunctionality) + - [SubType](#proto-SubType) + - [TokenFreezeStatus](#proto-TokenFreezeStatus) + - [TokenKeyValidation](#proto-TokenKeyValidation) + - [TokenKycStatus](#proto-TokenKycStatus) + - [TokenPauseStatus](#proto-TokenPauseStatus) + - [TokenSupplyType](#proto-TokenSupplyType) + - [TokenType](#proto-TokenType) + + + + + +

Top

+ +## basic_types.proto +# Basic Types +Fundamental message types used across transactions and state as field types. + +### Requirements for identifier values +- Most entities in the network SHALL be identified by a multi-part + identifier. These identifier values SHALL consist of a shard, a realm, and + an entity identifier. +- Shard, Realm, and Entity Number MUST all be whole numbers. +- A Shard SHALL be globally unique. +- A Realm MAY be reused between shards, but SHALL be unique within a shard. +- An Entity Number MAY be reused between shards and realms, but SHALL be + unique within each combination of shard and realm. +- Every object (e.g. account, file, token, etc...) SHALL be scoped to exactly + one realm and shard. Thus a File has a FileID, a numeric triplet, such as + 0.0.2 for shard 0, realm 0, entity 2. +- Identifier values SHOULD use an Entity Number as the third component of the + identifier. Some, however, MAY use alternative or composite values for the + Entity portion of the three part identifier. Any such alternative or + composite value MUST be unique within that shard and realm combination. +- The entity portion of the identifier, regardless of type, MUST be unique + within that realm and shard combination and MAY be globally unique. +- The triplet of shard.realm.entity MUST be globally unique, even across + different identifier types. +- Each realm SHALL maintain a single counter for entity numbers, so if there + is an identifier with value 0.1.2, then there MUST NOT be an identifier + with value 0.1.2 for any other object. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### AccountAmount +An account, and the amount that it sends or receives during a token transfer. + +This message is only relevant to fungible/common token transfers. +Non-fungible/unique (NFT) token transfers MUST use the NftTransfer message. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| accountID | [AccountID](#proto-AccountID) | | An Account identifier that will send or receive token(s). | +| amount | [sint64](#sint64) | | An amount to send (negative) or receive (positive).

This amount MUST be denominated in the smallest unit of the relevant token.
For HBAR this SHALL be tinybar (10-8 HBAR).
For other fungible/common tokens this SHALL depend on the value of `decimals` for that token. | +| is_approval | [bool](#bool) | | An approved allowance flag.
If true then the transfer is expected to be an approved allowance.

If set, `accountID` SHALL be the owner that previously approved the allowance.
The default value SHALL be false (unset). | + + + + + + + + +### AccountID +A unique identifier for an Hedera account. + +An account identifier is of the form `shard.realm.[number|alias]`.
+The identifier MAY use the alias form when transferring HBAR to a public key +before the account for that key is created, when only the alias value is +known, or in some smart contracts that use the EVM address style alias to +refer to Accounts.
+When the account entry is completed, the alias SHALL be stored separately in +the Account record, and the identifier in the Account SHALL use the +`accountNum` form. + +--- +### Additional Notes + +#### Alias +There is considerable complexity with `alias` (aka `evm_address`) for +Accounts. Much of this comes from the existence of a "hidden" alias for +almost all accounts, and the reuse of the alias field for both EVM reference +and "automatic" account creation.
+For the purposes of this specification, we will use the following terms for +clarity. + - `key_alias`
+ The account public key as a protobuf serialized message and used for + auto-creation and subsequent lookup. This is only valid if the account + key is a single `primitive` key, either Ed25519 or ECDSA_SECP256K1. + - `evm_address`
+ Exists for every account and is one of + - `contract_address`
+ The 20 byte EVM contract address per EIP-1014 + - `evm_key_address`
+ The keccak-256 hash of an ECDSA_SECP256K1 `primitive` key. + - This is for accounts lazy-created from EVM public keys, when the + corresponding ECDSA_SECP256K1 public key is presented in a + transaction signed by the private key for that public key, the + account is created that key assigned, and the protobuf-serialized + form is set as the account alias. + - `long_zero`
+ A synthetic 20 byte address inferred for "normally" created accounts. + It is constructed from the "standard" AccountID as follows. + 1. 4 byte big-endian shard number + 1. 8 byte big-endian realm number + 1. 8 byte big-endian entity number
+ +The `alias` field in the `Account` message SHALL contain one of four values +for any given account. + - The `key_alias`, if the account was created by transferring HBAR to the + `key_alias` public key value. + - The `evm_key_address` if the account was created from an EVM public key + - The `contract_address` if the account belongs to an EVM contract + - Not-Set/null/Bytes.EMPTY (collectively `null`) if the account was + created normally + +If the `alias` field of an `Account` is any form of `null`, then the account +MAY be referred to by `alias` in an `AccountID` by using the `long_zero` +address for the account.
+This "hidden default" alias SHALL NOT be stored, but is synthesized by the +node software as needed, and may be synthesized by an EVM contract or client +software as well. +--- + +#### Alias forms +An `AccountID` in a transaction MAY reference an `Account` with +`shard.realm.alias`.
+If the account `alias` field is set for an Account, that value SHALL be the +account alias.
+If the account `alias` field is not set for an Account, the `long_zero` alias +SHALL be the account alias. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| shardNum | [int64](#int64) | | A whole number shard identifier. | +| realmNum | [int64](#int64) | | A whole number realm identifier. | +| accountNum | [int64](#int64) | | A whole number account number, unique within its realm and shard.

For any AccountID fields in the query response, transaction records, transaction receipts, or block stream `accountNum` MUST be used. | +| alias | [bytes](#bytes) | | An alias value.
Alias is a value used in some contexts to refer to an account when account number is not available, and may be an alias public key, or an EVM address. | + + + + + + + + +### ContractID +An identifier for a smart contract within the network. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| shardNum | [int64](#int64) | | A whole number shard identifier. | +| realmNum | [int64](#int64) | | A whole number realm identifier. | +| contractNum | [int64](#int64) | | A whole number contract identifier, unique within its realm and shard. | +| evm_address | [bytes](#bytes) | | A 20-byte EVM address of the contract to call.

Every contract has an EVM address determined by its `shard.realm.num` identifier. This address is as follows:

  1. 4 byte big-endian shard number
  2. 8 byte big-endian realm number
  3. 8 byte big-endian contract number
This address is not stored in state, but is computed when needed.

Contracts created via CREATE2 have an additional, primary address that is derived from the EIP-1014 specification, and does not have a simple relation to a `shard.realm.num` id.

(Note that CREATE2 contracts MAY also be referred to by the three-part EVM address described above.) | + + + + + + + + +### CurrentAndNextFeeSchedule +The "current" fee schedule and the "next" fee schedule. + +The current fee schedule is the schedule that SHALL apply to the current +transaction.
+The next fee schedule is the schedule that SHALL apply after the current +schedule expires.
+We store both to avoid a condition where transactions are processed very +near the time when a fee schedule expires and it might be indeterminate +which fees to apply. With both current and next fee schedule the network +can deterministically apply the correct fee schedule based on consensus +timestamp for each transaction. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| currentFeeSchedule | [FeeSchedule](#proto-FeeSchedule) | | A current, unexpired, fee schedule. | +| nextFeeSchedule | [FeeSchedule](#proto-FeeSchedule) | | A future fee schedule to use when the current schedule expires. | + + + + + + + + +### FeeComponents +A set of values the nodes use in determining transaction and query fees, and +constants involved in fee calculations. + +Nodes SHALL multiply the amount of "resources" allocated to a transaction or +query by the corresponding price to calculate the appropriate fee. Units are +one-thousandth of a `tinyCent`. The "resource" allocations SHALL be estimated +based on transaction characteristics and current network state, and MAY be +further adjusted based on network load and congestion. + +This SHALL be used, in different contexts, for the cost _factors_ used to +calculate charged amounts, for the resource accumulation, and for actual +amounts to be charged.
+Amounts recorded here MUST be converted to tinybar according to the +current active `ExchangeRate` for the network. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| min | [int64](#int64) | | Base: "minimum total fee".

The calculated fee MUST be greater than this value. | +| max | [int64](#int64) | | Base: "maximum total fee".

The calculated fee MUST be less than this value. | +| constant | [int64](#int64) | | Base: "constant fee".
A baseline constant contribution to total fee. | +| bpt | [int64](#int64) | | Bandwidth: "bytes per transaction".
The fee for bandwidth consumed by a transaction, measured in bytes | +| vpt | [int64](#int64) | | Signatures: "validations per transaction".
The fee for signature verifications required by a transaction | +| rbh | [int64](#int64) | | Memory: "RAM byte-hours".
The fee for RAM required to process a transaction, measured in byte-hours | +| sbh | [int64](#int64) | | Disk: "storage byte-hours".
The fee for storage required by a transaction, measured in byte-hours | +| gas | [int64](#int64) | | Compute: Ethereum term for a derivative EVM compute resource.
The fee of computation for a smart contract transaction. The value of gas is set by a conversion rate, and is regularly updated to reflect reasonable and customary costs. | +| tv | [int64](#int64) | | Ad valorem: "transferred value".
The fee for HBAR transferred by a transaction. | +| bpr | [int64](#int64) | | Response memory: "bytes per response".
The fee for data retrieved from memory to deliver a response, measured in bytes | +| sbpr | [int64](#int64) | | Response disk: "storage bytes per response".
The fee for data retrieved from disk to deliver a response, measured in bytes | + + + + + + + + +### FeeData +A total fee, in component amounts charged for a transaction. + +Total fees are composed of three sets of components. +- Node data, components that compensate the specific node that submitted + the transaction. +- Network data, components that compensate the Hedera network for gossiping + the transaction and determining the consensus timestamp. +- Service data, components that compensate the Hedera network for the ongoing + maintenance and operation of the network, as well as ongoing development + of network services. + +Fee components are recorded in thousandths of a tiny cent, and the network +exchange rate converts these to tinybar amounts, which are what the network +charges for transactions and what the network reports in the record stream. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| nodedata | [FeeComponents](#proto-FeeComponents) | | Fee components to be paid to the submitting node. | +| networkdata | [FeeComponents](#proto-FeeComponents) | | Fee components to be paid to the network for bringing a transaction to consensus. | +| servicedata | [FeeComponents](#proto-FeeComponents) | | Fee components to be paid to the network for providing the immediate and ongoing services associated with executing the transaction, maintaining the network, and developing the network software. | +| subType | [SubType](#proto-SubType) | | A sub-type distinguishing between different types of `FeeData` that may apply to the same base transaction type (associated with an `HederaFunctionality`). | + + + + + + + + +### FeeSchedule +A set of fee schedules covering all transaction types and query types, along +with a specific time at which this fee schedule will expire. + +Nodes SHALL use the most recent unexpired fee schedule to determine the fees +for all transactions based on various resource components imputed to each +transaction. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| transactionFeeSchedule | [TransactionFeeSchedule](#proto-TransactionFeeSchedule) | repeated | Sets of fee coefficients for various transaction or query types. | +| expiryTime | [TimestampSeconds](#proto-TimestampSeconds) | | A time, in seconds since the `epoch`, when this fee schedule will expire.

For this purpose, `epoch` SHALL be the UNIX epoch with 0 at `1970-01-01T00:00:00.000Z`. | + + + + + + + + +### FileID +An identifier for a File within the network. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| shardNum | [int64](#int64) | | A whole number shard identifier. | +| realmNum | [int64](#int64) | | A whole number realm identifier. | +| fileNum | [int64](#int64) | | A whole number File identifier, unique within its realm and shard. | + + + + + + + + +### Fraction +A rational number.
+A common use is to set the amount of a value transfer to collect as a +custom fee. + +It is RECOMMENDED that both numerator and denominator be no larger than +necessary to express the required fraction. A very large numerator, in +particular, may not be reliable. +Both fields are REQUIRED and SHOULD be positive integers. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| numerator | [int64](#int64) | | A fractional number's numerator. | +| denominator | [int64](#int64) | | A fractional number's denominator.

A zero value SHALL fail with response code `FRACTION_DIVIDES_BY_ZERO`. | + + + + + + + + +### Key +A Key is an entity representing one or more cryptographic public/private key +pairs and, optionally, the structure for how multiple signatures may be +composed to meet complex multiple-signature authorization requirements. + +A Key can be a public key from either the Ed25519 or ECDSA(secp256k1) +signature schemes. In the ECDSA(secp256k1) case we require the 33-byte +compressed form of the public key. For simplicity, we call these +cryptographic public keys `primitive` keys.
+If an entity has a primitive key associated to it, then the corresponding +private key must sign any transaction to send tokens or perform other +actions requiring authorization. + +A Key can also be the ID of a smart contract instance, which is then +authorized to perform any precompiled contract action that requires +authorization by that key.
+Note that when a key is a smart contract ID, it SHALL NOT imply that the +contract with that ID will actually create a cryptographic signature. +It SHALL signify that when the contract calls a precompiled contract, the +resulting "child transaction" SHALL be implicitly authorized to perform any +action controlled by that key. A contract ID key MAY be "delegatable", which +permits that contract to "authorize" a message frame for which it is +recipient, even if the _code_ within that message frame is from a different +contract. + +A Key can be a "threshold key", which is a list of N keys, any M of which +may sign in order for the signature to be considered valid. The value of +M for a given threshold key MUST be less than or equal to N. A threshold +key is sometimes called a "M-of-N" key. + +A Key can be a "key list" where all keys in the list must sign unless +specified otherwise in the documentation for a specific transaction +type (e.g. FileDeleteTransactionBody).
+This implies that the use of a key list is dependent on context. For +example, an Hedera file that is created with a list of keys, SHALL require +that all of those keys must sign a transaction to create or modify the file, +but only one key from that list MUST sign a transaction to delete the file. +So it is a single list that sometimes acts as a N-of-N threshold key, and +sometimes acts as a 1-of-N threshold key.
+To reduce confusion this may cause, a key list SHALL always be considered +N-of-N, unless specified otherwise in official documentation.
+A key list MAY have repeated primitive public keys, but the signature +requirement for all keys in a repeated set SHALL be satisfied by a single +valid signature. There is no mechanism to require a single key to sign a +single transaction more than once. + +Any list or threshold key MAY have nested key lists or threshold keys. +This allows, for example, the keys within a threshold signature to +themselves be threshold, list, contract, or primitive keys. This nesting +structure enables complex asymmetric multi-party signature requirements to +be met. + +To ensure adequate performance and transaction security, key nesting is +limited to at most fifteen(15) levels. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| contractID | [ContractID](#proto-ContractID) | | A smart contract instance that is authorized implicitly.

This key type SHALL require that the code in the active message frame belong to the contract with the given id. | +| ed25519 | [bytes](#bytes) | | An array of Ed25519 public key bytes. | +| RSA_3072 | [bytes](#bytes) | | **Deprecated.** This option is not currently supported.
An array of RSA-3072 public key bytes. | +| ECDSA_384 | [bytes](#bytes) | | **Deprecated.** This option is not currently supported.
An array of ECDSA, using the p-384 curve, public key bytes. | +| thresholdKey | [ThresholdKey](#proto-ThresholdKey) | | A threshold, M, combined with a list of N keys, any M of which are sufficient to form a valid signature. | +| keyList | [KeyList](#proto-KeyList) | | A list of keys. This may be treated like a "N-of-N" threshold key, as a component of another key, or in some other manner as documented. | +| ECDSA_secp256k1 | [bytes](#bytes) | | A set of compressed ECDSA(secp256k1) public key bytes.
This is an EVM compatibility format. | +| delegatable_contract_id | [ContractID](#proto-ContractID) | | A smart contract that, if the recipient of the active message frame, SHALL be imputed authorization.
Setting this key type is a more permissive version of setting a contractID key.

This key form SHALL NOT strictly require that the code being executed in the frame belong to the given contract. The code in frame MAY be running another contract via a `delegatecall`. | + + + + + + + + +### KeyList +A list of keys.
+A `KeyList` requires all keys (N-of-N) to sign, unless otherwise +specified in official documentation. A KeyList may contain repeated keys, +but all such repeated keys are considered a single key when determining +signature authorization. + +### Additional Notes +1. An empty key list is the "standard" mechanism to represent an + unassigned key. For example, if the `admin_key` of a token is set + to the empty key list, then that token has no admin key, and + functionality that requires an admin key to sign the + transaction is disabled. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| keys | [Key](#proto-Key) | repeated | A list of keys. All values in this list SHALL be non-null.

| + + + + + + + + +### NftID +An identifier for a unique token (or "NFT"), used by both contract +and token services. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| token_ID | [TokenID](#proto-TokenID) | | A token identifier.
This token represents the collection containing this NFT. | +| serial_number | [int64](#int64) | | A unique serial number.
This serial number is unique within its token type. | + + + + + + + + +### NftTransfer +A NFT transfer.
+This refers to a sender account, a receiver account, and the serial number +of an NFT to transfer from sender to receiver. + +Each `NftTransfer` SHALL be contained in another message (typically +`TokenTransferList`) that details which `Token` type applies to this NFT +transfer. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| senderAccountID | [AccountID](#proto-AccountID) | | An Account identifier for the sender. | +| receiverAccountID | [AccountID](#proto-AccountID) | | An Account identifier for the receiver. | +| serialNumber | [int64](#int64) | | A serial number for the NFT to transfer. | +| is_approval | [bool](#bool) | | An approved allowance flag.
If true then the transfer is expected to be an approved allowance.

If set, `senderAccountID` SHALL be the owner that previously approved the allowance.
The default value SHALL be false (unset). | + + + + + + + + +### NodeAddress +The data about a node, including its service endpoints and the Hedera account +to be paid for services provided by the node (that is, queries answered and +transactions submitted). + +All active fields are populated in the `0.0.102` address book file.
+Only fields documented with "`0.0.101` field" are populated in the 0.0.101 +address book file. + +This message MAY be superseded by messages in state/addressbook/node.proto +and node_get_info.proto. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| ipAddress | [bytes](#bytes) | | **Deprecated.** ServiceEndpoint is now used to retrieve a node's list of IP addresses and ports.
The IP address of the Node, as a string, encoded in UTF-8.
This value SHALL NOT be populated. | +| portno | [int32](#int32) | | **Deprecated.** ServiceEndpoint is now used to retrieve a node's list of IP addresses and ports.
The port number of the grpc server for the node.
This value SHALL NOT be populated. | +| memo | [bytes](#bytes) | | **Deprecated.** Description provides short text functionality.
A short description of the node.

This field SHALL NOT be populated. | +| RSA_PubKey | [string](#string) | | A hexadecimal String encoding of an X509 public key.

This X509 RSA _public_ key SHALL be used to verify record stream files (e.g., record stream files).
This field SHALL be a string of hexadecimal characters, encoded UTF-8, which, translated to binary, form the public key DER encoding. | +| nodeId | [int64](#int64) | | A numeric identifier for the node.

This value SHALL NOT be sequential.

A `0.0.101` field | +| nodeAccountId | [AccountID](#proto-AccountID) | | An account to be paid the "node" portion of transaction fees.
The "node" fees are paid to the node that submitted the transaction.

A `0.0.101` field | +| nodeCertHash | [bytes](#bytes) | | A hash of the node's TLS certificate.

This field SHALL be a string of hexadecimal characters, encoded UTF-8, which, translated to binary, form a SHA-384 hash of the node's TLS certificate in PEM format. This TLS certificate MUST be encoded UTF-8 and normalized according to the NFKD form prior to computing the hash value.
The value of this field SHALL be used to verify the node TLS certificate when presented during protocol negotiation.

A `0.0.101` field | +| serviceEndpoint | [ServiceEndpoint](#proto-ServiceEndpoint) | repeated | A node's service IP addresses and TCP ports.
Nodes require multiple endpoints to ensure that inter-node communication (e.g. gossip) is properly separated from client communication to API endpoints.

A `0.0.101` field | +| description | [string](#string) | | A short description of the node.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8. | +| stake | [int64](#int64) | | **Deprecated.** This is replaced by per-account stake tracking and dynamic calculation.
The amount of tinybar staked to the node.
This value SHOULD NOT be populated, and SHALL be ignored. | + + + + + + + + +### NodeAddressBook +A list of nodes and their metadata that contains details of the nodes +running the network. + +Used to parse the contents of system files `0.0.101` and `0.0.102`. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| nodeAddress | [NodeAddress](#proto-NodeAddress) | repeated | Published data for all nodes in the network | + + + + + + + + +### PendingAirdropId +A unique, composite, identifier for a pending airdrop. + +Each pending airdrop SHALL be uniquely identified by +a `PendingAirdropId`.
+A `PendingAirdropId` SHALL be recorded when created and MUST be provided in +any transaction that would modify that pending airdrop +(such as a `claimAirdrop` or `cancelAirdrop`). + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| sender_id | [AccountID](#proto-AccountID) | | A sending account.

This is the account that initiated, and SHALL fund, this pending airdrop.
This field is REQUIRED. | +| receiver_id | [AccountID](#proto-AccountID) | | A receiving account.

This is the ID of the account that SHALL receive the airdrop.
This field is REQUIRED. | +| fungible_token_type | [TokenID](#proto-TokenID) | | A token identifier.
This is the type of token for a fungible/common token airdrop.

This field is REQUIRED for a fungible/common token and MUST NOT be used for a non-fungible/unique token. | +| non_fungible_token | [NftID](#proto-NftID) | | The id of a single NFT
This is the type of token for a non-fungible/unique token airdrop and consists of a Token ID and serial number.

This field is REQUIRED for a non-fungible/unique token and MUST NOT be used for a fungible/common token. | + + + + + + + + +### PendingAirdropValue +A single pending airdrop value. + +This message SHALL record the airdrop amount for a +fungible/common token.
+This message SHOULD be null for a non-fungible/unique token.
+If a non-null `PendingAirdropValue` is set for a non-fungible/unique +token, the amount field MUST be `0`. + +It is RECOMMENDED that implementations store pending airdrop information +as a key-value map from `PendingAirdropId` to `PendingAirdropValue`, with +a `null` value used for non-fungible pending airdrops. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| amount | [uint64](#uint64) | | An amount to transfer for fungible/common tokens.
This is expressed in the smallest available units for that token (i.e. 10-`decimals` whole tokens).

This amount SHALL be transferred from the sender to the receiver, if claimed.
If the token is a fungible/common token, this value MUST be strictly greater than `0`.
If the token is a non-fungible/unique token, this message SHOULD NOT be set, and if set, this field MUST be `0`. | + + + + + + + + +### RealmID +A realm identifier.
+Within a given shard, every realm has a unique numeric identifier. +Each account, file, and contract instance belongs to exactly one realm. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| shardNum | [int64](#int64) | | A whole number shard identifier. | +| realmNum | [int64](#int64) | | A whole number realm identifier. | + + + + + + + + +### ScheduleID +An unique identifier for a Schedule + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| shardNum | [int64](#int64) | | A whole number shard | +| realmNum | [int64](#int64) | | A whole number realm | +| scheduleNum | [int64](#int64) | | A whole number schedule, unique within its realm and shard | + + + + + + + + +### SemanticVersion +A software version according to "[semantic versioning](https://semver.org/)" +or "date versioning". + +Hedera currently modifies the "typical" semantic versioning somewhat, the +`major` version is always `0`, and each release increments the `minor` +version. The `patch` and `pre` components are used in the typical manner. +The `build` component is not generally used. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| major | [int32](#int32) | | A major version.
Hedera does not increment this value and retains a `0` value to indicate that API may change for any release.

This value SHALL increment for an incompatible API change.
| +| minor | [int32](#int32) | | A minor version.
Hedera increments this value with each release.
There may be incompatible API changes in any Hedera Services release.

This value SHALL increment for backwards-compatible new functionality. | +| patch | [int32](#int32) | | A patch version.

This value SHALL increment for backwards-compatible bug fixes. | +| pre | [string](#string) | | A pre-release version.

This MAY be denoted by appending a hyphen and a series of dot separated identifiers per [Semver Specification](https://semver.org/#spec-item-9); given a string `0.14.0-alpha.1+21AF26D3`, this field would contain 'alpha.1' | +| build | [string](#string) | | A build version.

Build version MAY be denoted by appending a plus sign and a series of dot separated identifiers immediately following the patch or pre-release version per [Semver Specification](https://semver.org/#spec-item-10); so given a string `0.14.0-alpha.1+21AF26D3`, this field would contain '21AF26D3' | + + + + + + + + +### ServiceEndpoint +A network node endpoint.
+Each network node in the global address book publishes one or more endpoints +which enable the nodes to communicate both with other nodes, for gossip, and +with clients to receive transaction requests. + +This message supports IPv4 with address and TCP port, +and MAY include a FQDN instead of an IP address.
+IPv6 is not currently supported. + +When the `domain_name` field is set, the `ipAddressV4` field +MUST NOT be set.
+When the `ipAddressV4` field is set, the `domain_name` field +MUST NOT be set. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| ipAddressV4 | [bytes](#bytes) | | A 32-bit IPv4 address.
This is the address of the endpoint, encoded in pure "big-endian" (i.e. left to right) order (e.g. `127.0.0.1` has hex bytes in the order `7F`, `00`, `00`, `01`). | +| port | [int32](#int32) | | A TCP port to use.

This value MUST be between 0 and 65535, inclusive. | +| domain_name | [string](#string) | | A node domain name.

This MUST be the fully qualified domain name of the node.
This value MUST NOT exceed 253 characters.
When the `domain_name` field is set, the `ipAddressV4` field MUST NOT be set.
When the `ipAddressV4` field is set, the `domain_name` field MUST NOT be set. | + + + + + + + + +### ServicesConfigurationList +Setting values representing a source of runtime configuration information. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| nameValue | [Setting](#proto-Setting) | repeated | A List of `Setting` values, typically read from application properties. | + + + + + + + + +### Setting +A single runtime configuration setting. + +Typically a name-value pair, this may also contain a small amount of +associated data. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| name | [string](#string) | | A name for this setting property. | +| value | [string](#string) | | A value for this setting property. | +| data | [bytes](#bytes) | | A small quantity of data associated with this setting.

This SHOULD be less than 100 bytes.
If the value is a string, it MUST be encoded UTF-8. | + + + + + + + + +### ShardID +A shard identifier.
+A shard is a partition of nodes running the network that processes +transactions separately from other shards. Each shard is effectively an +independent instance of the overall network that shares the same virtual +distributed ledger, and may gossip cross-shard transactions with other +shards to maintain overall correct processing of the ledger. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| shardNum | [int64](#int64) | | A whole number shard identifier. | + + + + + + + + +### Signature +This message is deprecated and MUST NOT be used to communicate with +network nodes. It is retained here only for historical reasons. + +Client software MUST NOT include this message in any request.
+Compliant nodes SHALL NOT accept any request containing this message. + +Please use the `SignaturePair` and `SignatureMap` messages instead of +this message. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| contract | [bytes](#bytes) | | Smart contract virtual signature (always length zero). | +| ed25519 | [bytes](#bytes) | | Ed25519 signature bytes. | +| RSA_3072 | [bytes](#bytes) | | RSA-3072 signature bytes. | +| ECDSA_384 | [bytes](#bytes) | | ECDSA p-384 signature bytes. | +| thresholdSignature | [ThresholdSignature](#proto-ThresholdSignature) | | A list of signatures for a single N-of-M threshold Key. This must be a list of exactly M signatures, at least N of which are non-null. | +| signatureList | [SignatureList](#proto-SignatureList) | | A list of M signatures, each corresponding to a Key in a KeyList of the same length. | + + + + + + + + +### SignatureList +This message is deprecated and MUST NOT be used to communicate with network +nodes. It is retained here only for historical reasons. + +Client software MUST NOT include this message in any request.
+Compliant nodes SHALL NOT accept any request containing this message. + +Please use the `SignaturePair` and `SignatureMap` messages instead of +this message. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| sigs | [Signature](#proto-Signature) | repeated | Each signature corresponds to a Key in the KeyList. | + + + + + + + + +### SignatureMap +A set of signatures corresponding to every unique public key that +signed a given transaction. + +If any public key matches more than one prefix in the signature map, +the transaction containing that map SHALL fail immediately with the +response code `KEY_PREFIX_MISMATCH`. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| sigPair | [SignaturePair](#proto-SignaturePair) | repeated | A list of signature pairs for a specific transaction.
Each signature pair represents a single cryptographic (`primitive`) public key identified by a "prefix" value and the cryptographic signature produced for that key. | + + + + + + + + +### SignaturePair +A public key and signature pair.
+Only Ed25519 and ECDSA(secp256k1) keys and signatures are currently supported +as cryptographic (non-implied) signatures. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| pubKeyPrefix | [bytes](#bytes) | | Prefix bytes of the public key.

The client may use any number of bytes from zero to the whole length of the public key for pubKeyPrefix. If zero bytes are used, then it MUST be true that only one cryptographic key is required to sign the associated transaction.
If the `pubKeyPrefix` is 0 bytes and more than a single cryptographic key is required to sign the transaction, the request SHALL resolve to `INVALID_SIGNATURE`.

Important Note

In the special case that a signature is provided to authorize a precompiled contract, the `pubKeyPrefix` MUST contain the _entire public key_.
That is, if the key is an Ed25519 key, the `pubKeyPrefix` MUST be 32 bytes long and contain the full public key bytes.
If the key is an ECDSA(secp256k1) key, the `pubKeyPrefix` MUST be 33 bytes long and contain the full _compressed_ form of the public key. | +| contract | [bytes](#bytes) | | A smart contract virtual signature.

This value MUST be length zero, if set. | +| ed25519 | [bytes](#bytes) | | An Ed25519 signature. | +| RSA_3072 | [bytes](#bytes) | | **Deprecated.** This option is not supported.
A RSA-3072 signature. | +| ECDSA_384 | [bytes](#bytes) | | **Deprecated.** This option is not supported.
ECDSA p-384 signature. | +| ECDSA_secp256k1 | [bytes](#bytes) | | An ECDSA(secp256k1) signature. | + + + + + + + + +### StakingInfo +Staking information for an account or a contract. + +This is used for responses returned from `CryptoGetInfo` or +`ContractGetInfo` queries. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| decline_reward | [bool](#bool) | | A flag indicating that the holder of this account has chosen to decline staking rewards. | +| stake_period_start | [Timestamp](#proto-Timestamp) | | A `Timestamp` of the start time for the latest active staking period.

This MUST be a period during which either the staking settings for this account or contract changed or the account or contract received staking rewards, whichever is later. Examples of a change in staking settings include starting staking or changing the staked_node_id.
If this account or contract is not currently staked to a node, then this field SHALL NOT be set. | +| pending_reward | [int64](#int64) | | An amount, in tinybar, to be received in the next reward payout.
Rewards are not paid out immediately; for efficiency reasons rewards are only paid out as part of another transaction involving that account. | +| staked_to_me | [int64](#int64) | | A proxy-staked balance.
The total HBAR balance of all accounts that delegate staking to this account or contract. | +| staked_account_id | [AccountID](#proto-AccountID) | | A delegated stake.

This account delegates to the indicated account for staking purposes. | +| staked_node_id | [int64](#int64) | | A direct stake.

This accounts stakes its balance to the designated node. | + + + + + + + + +### ThresholdKey +A threshold value and a list of public keys that, together, form a threshold +signature requirement. Any subset of the keys in the list may satisfy the +signature requirements of this type of key, provided the number of keys meets +or exceeds the threshold. For example, if a particular key has a threshold of +three(3) and eight(8) keys in the list, then any three(3) signatures, from +the list of eight(8), is sufficient to authorize that key. + +For threshold purposes, all signatures from a single `primitive` key are +considered a single signature, so that signature(s) from a single key SHALL +NOT _directly_ meet a threshold greater than one(1). + +#### Note +> It is possible to construct a complex key structure that _would_ enable a +> single primitive key to successfully meet a threshold requirement. All +> threshold keys SHOULD be carefully audited to ensure no one `primitive` +> key, or smart contract, has disproportionate capability. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| threshold | [uint32](#uint32) | | A transaction MUST have valid signatures from at least this number of separate keys, from the `keys` list to be authorized by this key. | +| keys | [KeyList](#proto-KeyList) | | A list of the keys that MAY satisfy signature requirements of this key. | + + + + + + + + +### ThresholdSignature +This message is deprecated and MUST NOT be used to communicate with network +nodes. It is retained here only for historical reasons. + +Client software MUST NOT include this message in any request.
+Compliant nodes SHALL NOT accept any request containing this message. + +Please use the `SignaturePair` and `SignatureMap` messages, in combination +with `ThresholdKey` keys, instead of this message. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| sigs | [SignatureList](#proto-SignatureList) | | For an N-of-M threshold key, this is a list of M signatures, at least N of which must be non-null. | + + + + + + + + +### TokenAssociation +An association between a token and an account. + +An account must be associated with a token before that account can transact +in (send or receive) that token. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| token_id | [TokenID](#proto-TokenID) | | A token identifier for the associated token. | +| account_id | [AccountID](#proto-AccountID) | | An account identifier for the associated account. | + + + + + + + + +### TokenBalance +A number of _transferable units_ of a specified token. + +The transferable unit of a token is its smallest denomination, as given by +the token's `decimals` property. Each minted token contains +10`decimals` transferable units. For example, we could think of +the cent as the transferable unit of the US dollar (`decimals=2`); and the +tinybar as the transferable unit of HBAR (`decimals=8`). + +Transferable units are not directly comparable across different tokens. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| tokenId | [TokenID](#proto-TokenID) | | A token identifier. | +| balance | [uint64](#uint64) | | A number of transferable units of the identified token.

For fungible/common tokens this SHALL be the balance, in units of 10`-decimals` whole tokens.
For non-fungible/unique tokens, this SHALL be the number of individual unique tokens in this balance. | +| decimals | [uint32](#uint32) | | A number of "decimals" precision.

This MUST match the `decimals` value for the token identified by the `tokenId` field. | + + + + + + + + +### TokenBalances +A set of token balance values. + +Each entry describes the balance the enclosing account holds for a specific +token. The balance is an amount for a fungible/common token or a count for +a non-fungible/unique token. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| tokenBalances | [TokenBalance](#proto-TokenBalance) | repeated | A list of token balance values.
Each entry represents a single account balance for a single token. | + + + + + + + + +### TokenID +Unique identifier for a token.
+As with all entity identifiers within the network, a token identifier +consists of a combination of shard number, realm number, and entity number. +Each of these numbers is unique within its scope (shard > realm > entity). + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| shardNum | [int64](#int64) | | A whole number shard identifier. | +| realmNum | [int64](#int64) | | A whole number realm identifier. | +| tokenNum | [int64](#int64) | | A whole number token identifier. | + + + + + + + + +### TokenRelationship +An Hedera Token Service token relationship. A token relationship describes +the connection between an Account and a Token type, including the current +account balance in that token. + +A `TokenRelationship` SHALL contain, for the designated token and enclosing +account, The account's current balance, whether the account has KYC granted, +whether the assets are frozen and whether the association was automatic.
+A `TokenRelationship` MAY also contain the `symbol` and `decimals` values +copied from the token.
+`TokenRelationship` entries SHALL be valid only within the context of a +`GetAccountDetails` query response, or other enclosing message, which +specifies the account side of the relationship. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| tokenId | [TokenID](#proto-TokenID) | | A token identifier.

This MUST match an existing token that is not deleted. | +| symbol | [string](#string) | | A token symbol.

This MUST match an existing token that is not deleted.
This MUST match the value for the token identified in `tokenId`. | +| balance | [uint64](#uint64) | | An account balance for this token.

For fungible/common tokens this SHALL be the balance that the account holds of that token. The value is provided as an integer amount of the smallest unit of the token (i.e. 10`-decimals` whole tokens).
For non-fungible/unique tokens this SHALL be the whole number of unique tokens held by the account for this token type. | +| kycStatus | [TokenKycStatus](#proto-TokenKycStatus) | | A KYC status for the account with respect to this token.

This may be `KycNotApplicable`, `Granted` or `Revoked` and, if KYC is not supported for this token (e.g. the `kyc_key` of the token is not set), this SHALL be `KycNotApplicable`. | +| freezeStatus | [TokenFreezeStatus](#proto-TokenFreezeStatus) | | A Freeze status for the account with respect to this token.

This value SHALL be one of `FreezeNotApplicable`, `Frozen` or `Unfrozen`.
If the token cannot freeze account assets (e.g. the `freeze_key` of the token is not set), this SHALL be `FreezeNotApplicable`. | +| decimals | [uint32](#uint32) | | A maximum "precision" for this token.

This value MUST match the `decimals` field of the token identified in the `tokenId` field.
A single whole token SHALL be divided into at most 10`decimals` sub-units. | +| automatic_association | [bool](#bool) | | An automatic association flag.

This SHALL be set if the relationship was created implicitly (automatically).
This SHALL be unset if the relationship was created explicitly (manually) via a `TokenAssociate` transaction. | + + + + + + + + +### TokenTransferList +A list of transfers for a particular (non-HBAR) token type. + +A `TokenTransferList` applies to a single token type, but may contain many +individual transfers.
+Each transfer of a fungible/common token MUST specify an `accountID` and +`amount`. Amount SHALL be positive when the account receives tokens, and +SHALL be negative when the account sends tokens. The amount SHOULD NOT be +`0`.
+In a transfer list containing fungible/common tokens in the `transfers` +list, the sum of all such transfers MUST be zero (`0`). +Each transfer of a unique token SHALL specify both sender and receiver, as +well as the serial number transferred.
+A single `TokenTransferList` MUST contain `transfers` or `nftTransfers`, +but MUST NOT contain both. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| token | [TokenID](#proto-TokenID) | | A token identifier.
This is the token to be transferred. | +| transfers | [AccountAmount](#proto-AccountAmount) | repeated | A list of account amounts.

Each entry SHALL have an account and amount.
These transfers SHALL be "double-entry" style; the credits (positive amount) and debits (negative amount) MUST sum to 0, unless this transfer list is part of a `mint` or `burn` operation.
This SHALL be be set for fungible/common tokens and MUST be empty otherwise. | +| nftTransfers | [NftTransfer](#proto-NftTransfer) | repeated | A list of NftTransfers.

Each entry SHALL have a sender and receiver account, and the serial number of the unique token to transfer.
This SHALL be be set for non-fungible/unique tokens and SHALL be empty otherwise. | +| expected_decimals | [google.protobuf.UInt32Value](#google-protobuf-UInt32Value) | | An expected decimal precision.
This is the number of decimals a fungible/common token type is _expected_ to have.

The transfer SHALL fail with response code `UNEXPECTED_TOKEN_DECIMALS` if this is set and the actual decimals specified for the `Token` differ from this value.
If `nftTransfers` is set, then this value SHOULD NOT be set. | + + + + + + + + +### TopicID +An unique identifier for a topic.
+Topics are part of the consensus service, messages are published to a topic. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| shardNum | [int64](#int64) | | A whole number shard identifier. | +| realmNum | [int64](#int64) | | A whole number realm identifier. | +| topicNum | [int64](#int64) | | A whole number topic identifier, unique within its realm and shard. | + + + + + + + + +### TransactionFeeSchedule +The fee schedule for a specific transaction or query based on the fee data. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| hederaFunctionality | [HederaFunctionality](#proto-HederaFunctionality) | | An enumeration for a particular transaction or query.
The functionality type determines the base cost parameters. | +| feeData | [FeeData](#proto-FeeData) | | **Deprecated.** Use `fees` instead of this field.
Resource price coefficients. | +| fees | [FeeData](#proto-FeeData) | repeated | The resource price coefficients for transaction type and any applicable subtypes.
The multiple entries enable support for subtype price definitions. | + + + + + + + + +### TransactionID +A transaction identifier.
+This is used for retrieving receipts and records for a transaction +and internally by the network for detecting when duplicate transactions are +submitted. + +A transaction may be processed more reliably by submitting it to +several nodes, each with a different node account, but all with the same +TransactionID. Then, the transaction will take effect when the first of all +those nodes submits the transaction and it reaches consensus. The other +transactions SHALL NOT be executed (and SHALL result in a +`DUPLICATE_TRANSACTION` response).
+Multiple submission increase reliability on the assumption that an error in, +for example, network connectivity will not affect all nodes equally. Latency +might be slightly lower, if one node is handling intake significantly slower +than others, for example. The base transaction fee is required for each +submission, however, so the total fees charged are significantly higher when +using this approach. + +### Requirements +Each transaction identifier MUST be unique.
+Multiple transactions MAY be submitted with the same transaction +identifier, but all except the first SHALL be rejected as duplicate +transactions.
+An identifier MUST specify a `payer` account to be charged all fees +associated with the transaction.
+The `payer` account MUST exist and MUST have sufficient HBAR to pay all +transaction fees.
+An identifier MUST specify a "valid start time".
+The "valid start time" MUST be strictly _earlier_ than the current +network consensus time when submitted.
+The "valid start time" MUST NOT be more than `transaction.maxValidDuration` +seconds before the current network consensus time when submitted.
+A client-submitted transaction MUST NOT set the `scheduled` flag. + +### Additional Notes + +Additional items applicable to Scheduled Transactions: + + - The ID of a Scheduled Transaction, once executed, SHALL inherit both + `transactionValidStart` and `accountID` from the `ScheduleCreate` + transaction that created the schedule. + - The `scheduled` property SHALL be set for Scheduled Transactions. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| transactionValidStart | [Timestamp](#proto-Timestamp) | | A timestamp for the transaction start time.
This is the earliest expected start time for this transaction.

This value MUST be strictly less than `consensusTimestamp` when the transaction is submitted. | +| accountID | [AccountID](#proto-AccountID) | | An Account identifier.

The identified account SHALL pay transaction fees for this transaction. | +| scheduled | [bool](#bool) | | A scheduled transaction flag.
If set, this transaction represents the execution of a Schedule after all necessary signatures are gathered.

This flag MUST NOT be set in a user-submitted transaction. | +| nonce | [int32](#int32) | | An identifier for an internal transaction.
An internal transaction is one that was spawned as part of handling a user transaction. These internal transactions share the transactionValidStart and accountID of the user transaction, so a nonce is necessary to give them a unique TransactionID.

An example is when a "parent" ContractCreate or ContractCall transaction calls one or more HTS precompiled contracts; each of the "child" transactions spawned for a precompile has a transaction id with a different nonce.

This value MUST be unset for user-submitted transactions. | + + + + + + + + +### TransferList +A list of accounts and amounts to transfer. + +Each `AccountAmount` SHALL specify the account and the amount to +send(negative) or receive(positive).
+Each `TransferList` SHALL be contained in another message that contains +other details required to complete a transfer. This is typically a +`CryptoTransferTransactionBody` or `TransactionRecord`.
+The `TransferList` SHALL only be used for HBAR transfers. Other token types +MUST use the `TokenTransferList` message. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| accountAmounts | [AccountAmount](#proto-AccountAmount) | repeated | A list of AccountAmount pairs.
Each entry in this list is an account and an amount to transfer into it (positive) or out of it (negative) | + + + + + + + + + + +### BlockHashAlgorithm +A specific hash algorithm. + +We did not reuse Record Stream `HashAlgorithm` here because in all cases, +currently, this will be `SHA2_384` and if that is the default value then +we can save space by not serializing it, whereas `HASH_ALGORITHM_UNKNOWN` +is the default for Record Stream `HashAlgorithm`. + +Note that enum values here MUST NOT match the name of any other enum value +in the same `package`, as protobuf follows `C++` scope rules and all enum +_names_ are treated as global constants within the `package`. + +| Name | Number | Description | +| ---- | ------ | ----------- | +| SHA2_384 | 0 | A SHA2 algorithm SHA-384 hash.

This is the default value, if a field of this enumerated type is not set, then this is the value that will be decoded when the serialized message is read. | + + + + + +### HederaFunctionality +The transactions and queries supported by Hedera Hashgraph. + +| Name | Number | Description | +| ---- | ------ | ----------- | +| NONE | 0 | Unused - The first value is unused because this default value is ambiguous with an "unset" value and therefore should not be used. | +| CryptoTransfer | 1 | Transfer tokens among accounts. | +| CryptoUpdate | 2 | Update an account. | +| CryptoDelete | 3 | Delete an account. | +| CryptoAddLiveHash | 4 | Add a livehash to an account | +| CryptoDeleteLiveHash | 5 | Delete a livehash from an account | +| ContractCall | 6 | Execute a smart contract call. | +| ContractCreate | 7 | Create a smart contract. | +| ContractUpdate | 8 | Update a smart contract. | +| FileCreate | 9 | Create a "file" stored in the ledger. | +| FileAppend | 10 | Append data to a "file" stored in the ledger. | +| FileUpdate | 11 | Update a "file" stored in the ledger. | +| FileDelete | 12 | Delete a "file" stored in the ledger. | +| CryptoGetAccountBalance | 13 | Get the balance for an account. | +| CryptoGetAccountRecords | 14 | Get a full account record. | +| CryptoGetInfo | 15 | Get information about a token. | +| ContractCallLocal | 16 | Execute a local smart contract call.
Used by contracts to call other contracts. | +| ContractGetInfo | 17 | Get information about a smart contract. | +| ContractGetBytecode | 18 | Get the compiled bytecode that implements a smart contract. | +| GetBySolidityID | 19 | Get a smart contract record by reference to the solidity ID. | +| GetByKey | 20 | Get a smart contract by reference to the contract key. | +| CryptoGetLiveHash | 21 | Get the live hash for an account | +| CryptoGetStakers | 22 | Get the accounts proxy staking to a given account. | +| FileGetContents | 23 | Get the contents of a "file" stored in the ledger. | +| FileGetInfo | 24 | Get the metadata for a "file" stored in the ledger. | +| TransactionGetRecord | 25 | Get transaction record(s) for a specified transaction ID. | +| ContractGetRecords | 26 | Get all transaction records for a specified contract ID in the past 24 hours.
@deprecated since version 0.9.0 | +| CryptoCreate | 27 | Create a new account | +| SystemDelete | 28 | Delete a "system" "file" stored in the ledger.
"System" files are files with special purpose and ID values within a specific range.
These files require additional controls and can only be deleted when authorized by accounts with elevated privilege. | +| SystemUndelete | 29 | Undo the delete of a "system" "file" stored in the ledger.
"System" files are files with special purpose and ID values within a specific range.
These files require additional controls and can only be deleted when authorized by accounts with elevated privilege. This operation allows such files to be restored, within a reasonable timeframe, if deleted improperly. | +| ContractDelete | 30 | Delete a smart contract | +| Freeze | 31 | Stop all processing and "freeze" the entire network.
This is generally sent immediately prior to upgrading the network.
After processing this transactions all nodes enter a quiescent state. | +| CreateTransactionRecord | 32 | Create a Transaction Record.
This appears to be purely internal and unused. | +| CryptoAccountAutoRenew | 33 | Auto-renew an account.
This is used for internal fee calculations. | +| ContractAutoRenew | 34 | Auto-renew a smart contract.
This is used for internal fee calculations. | +| GetVersionInfo | 35 | Get version information for the ledger.
This returns a the version of the software currently running the network for both the protocol buffers and the network services (node). | +| TransactionGetReceipt | 36 | Get a receipt for a specified transaction ID. | +| ConsensusCreateTopic | 50 | Create a topic for the Hedera Consensus Service (HCS). | +| ConsensusUpdateTopic | 51 | Update an HCS topic. | +| ConsensusDeleteTopic | 52 | Delete an HCS topic. | +| ConsensusGetTopicInfo | 53 | Get metadata (information) for an HCS topic. | +| ConsensusSubmitMessage | 54 | Publish a message to an HCS topic. | +| UncheckedSubmit | 55 | Submit a transaction, bypassing intake checking. Only enabled in local-mode. | +| TokenCreate | 56 | Create a token for the Hedera Token Service (HTS). | +| TokenGetInfo | 58 | Get metadata (information) for an HTS token. | +| TokenFreezeAccount | 59 | Freeze a specific account with respect to a specific HTS token.

Once this transaction completes that account CANNOT send or receive the specified token. | +| TokenUnfreezeAccount | 60 | Remove a "freeze" from an account with respect to a specific HTS token. | +| TokenGrantKycToAccount | 61 | Grant KYC status to an account for a specific HTS token. | +| TokenRevokeKycFromAccount | 62 | Revoke KYC status from an account for a specific HTS token. | +| TokenDelete | 63 | Delete a specific HTS token. | +| TokenUpdate | 64 | Update a specific HTS token. | +| TokenMint | 65 | Mint HTS token amounts to the treasury account for that token. | +| TokenBurn | 66 | Burn HTS token amounts from the treasury account for that token. | +| TokenAccountWipe | 67 | Wipe all amounts for a specific HTS token from a specified account. | +| TokenAssociateToAccount | 68 | Associate a specific HTS token to an account. | +| TokenDissociateFromAccount | 69 | Dissociate a specific HTS token from an account. | +| ScheduleCreate | 70 | Create a scheduled transaction | +| ScheduleDelete | 71 | Delete a scheduled transaction | +| ScheduleSign | 72 | Sign a scheduled transaction | +| ScheduleGetInfo | 73 | Get metadata (information) for a scheduled transaction | +| TokenGetAccountNftInfos | 74 | Get NFT metadata (information) for a range of NFTs associated to a specific non-fungible/unique HTS token and owned by a specific account. | +| TokenGetNftInfo | 75 | Get metadata (information) for a specific NFT identified by token and serial number. | +| TokenGetNftInfos | 76 | Get NFT metadata (information) for a range of NFTs associated to a specific non-fungible/unique HTS token. | +| TokenFeeScheduleUpdate | 77 | Update a token's custom fee schedule.

If a transaction of this type is not signed by the token `fee_schedule_key` it SHALL fail with INVALID_SIGNATURE, or TOKEN_HAS_NO_FEE_SCHEDULE_KEY if there is no `fee_schedule_key` set. | +| NetworkGetExecutionTime | 78 | Get execution time(s) for one or more "recent" TransactionIDs. | +| TokenPause | 79 | Pause a specific HTS token | +| TokenUnpause | 80 | Unpause a paused HTS token. | +| CryptoApproveAllowance | 81 | Approve an allowance for a spender relative to the owner account, which MUST sign the transaction. | +| CryptoDeleteAllowance | 82 | Delete (unapprove) an allowance previously approved for the owner account. | +| GetAccountDetails | 83 | Get all the information about an account, including balance and allowances.
This does not get a list of account records. | +| EthereumTransaction | 84 | Perform an Ethereum (EVM) transaction.
CallData may be inline if small, or in a "file" if large. | +| NodeStakeUpdate | 85 | Used to indicate when the network has updated the staking information at the end of a staking period and to indicate a new staking period has started. | +| UtilPrng | 86 | Generate and return a pseudorandom number based on network state. | +| TransactionGetFastRecord | 87 | Get a record for a "recent" transaction. | +| TokenUpdateNfts | 88 | Update the metadata of one or more NFT's of a specific token type. | +| NodeCreate | 89 | Create a node | +| NodeUpdate | 90 | Update a node | +| NodeDelete | 91 | Delete a node | +| TokenReject | 92 | Transfer one or more token balances held by the requesting account to the treasury for each token type. | +| TokenAirdrop | 93 | Airdrop one or more tokens to one or more accounts. | +| TokenCancelAirdrop | 94 | Remove one or more pending airdrops from state on behalf of the sender(s) for each airdrop. | +| TokenClaimAirdrop | 95 | Claim one or more pending airdrops | + + + + + +### SubType +A transaction sub type.
+This enumeration enables a set of transaction base fees to be broadly +defined for a type of operation and also be modified, when necessary, +based on specifics of the operation. + +### Explanation +The resource cost for a TokenMint operation is different between minting +fungible/common and non-fungible/unique tokens. This `enum` is used to +"mark" a cost as applying to one or the other.
+Similarly, the resource cost for a basic `tokenCreate` without a custom +fee schedule may yield a _base_ fee of $1. The resource cost for a +`tokenCreate` _with_ a custom fee schedule is different and may yield a +_base_ fee of $2 or more. + +| Name | Number | Description | +| ---- | ------ | ----------- | +| DEFAULT | 0 | The resource cost for the transaction type has no additional attributes | +| TOKEN_FUNGIBLE_COMMON | 1 | The resource cost for the transaction type includes an operation on a fungible/common token | +| TOKEN_NON_FUNGIBLE_UNIQUE | 2 | The resource cost for the transaction type includes an operation on a non-fungible/unique token | +| TOKEN_FUNGIBLE_COMMON_WITH_CUSTOM_FEES | 3 | The resource cost for the transaction type includes an operation on a fungible/common token with a custom fee schedule | +| TOKEN_NON_FUNGIBLE_UNIQUE_WITH_CUSTOM_FEES | 4 | The resource cost for the transaction type includes an operation on a non-fungible/unique token with a custom fee schedule | +| SCHEDULE_CREATE_CONTRACT_CALL | 5 | The resource cost for the transaction type includes a ScheduleCreate containing a ContractCall. | + + + + + +### TokenFreezeStatus +Possible token freeze status values. + +This is returned by `TokenGetInfoQuery` or `CryptoGetInfoResponse` +in `TokenRelationship`. + +| Name | Number | Description | +| ---- | ------ | ----------- | +| FreezeNotApplicable | 0 | The token does not support freeze or cannot be frozen for the designated account.
Typically this indicates that the token does not have a `freeze_key` set. | +| Frozen | 1 | The token is currently frozen for the designated account. | +| Unfrozen | 2 | The token is not currently frozen for the designated account. | + + + + + +### TokenKeyValidation +Types of validation strategies for token keys. + +| Name | Number | Description | +| ---- | ------ | ----------- | +| FULL_VALIDATION | 0 | Perform all token key validations.
This is the default value and behavior. | +| NO_VALIDATION | 1 | Perform no validations at all for all passed token keys. | + + + + + +### TokenKycStatus +Possible token "KYC" status values. + +This is returned by `TokenGetInfoQuery` or `CryptoGetInfoResponse` +in `TokenRelationship`. + +| Name | Number | Description | +| ---- | ------ | ----------- | +| KycNotApplicable | 0 | The token does not support KYC or cannot grant KYC for the designated account.
Typically this indicates that the token does not have a `kyc_key` set. | +| Granted | 1 | The designated account is currently granted KYC status for the designated token. | +| Revoked | 2 | The designated account is not currently granted KYC status for the designated token. | + + + + + +### TokenPauseStatus +Possible Pause status values. + +This is returned by `TokenGetInfoQuery` in `TokenRelationship`. + +| Name | Number | Description | +| ---- | ------ | ----------- | +| PauseNotApplicable | 0 | The token does not support pause or cannot be paused.
Typically this indicates that the token does not have a `pause_key` set. | +| Paused | 1 | The token is currently paused. | +| Unpaused | 2 | The token is not currently paused. | + + + + + +### TokenSupplyType +Possible Token Supply Types (IWA Compatibility). + +This `enum` indicates the limit of tokens that can exist during the +lifetime of a token definition. The "infinite" supply is only theoretically +infinite, as it is still limited to the magnitude of a 64-bit signed +integer. A "finite" supply is further limited to a value specified when +the token is created (or updated, if not immutable). + +| Name | Number | Description | +| ---- | ------ | ----------- | +| INFINITE | 0 | An unlimited supply.
This indicates that tokens of this type have an upper bound of Long.MAX_VALUE.
The supply is accounted in the smallest units of the token (i.e. 10-`decimals` whole tokens) | +| FINITE | 1 | A limited supply.
This indicates that tokens of this type have an upper bound of `maxSupply`.
The maximum supply SHALL be provided on token creation, but MAY be changed thereafter if the token has an `admin_key` set. | + + + + + +### TokenType +Possible Token Types (IWA Compatibility). + +Apart from fungible and non-fungible, Tokens can have either a common or +unique representation. Furthermore, tokens can have intrinsic or referential +value, and can be whole and indivisible or fractional.
+These distinction might seem subtle, but it is important when considering +how tokens can be traced, used, transferred, and if they can have isolated +unique properties. + +A few examples (these may not match enumerations below) using IWA taxonomy. +

+
fungible, whole, intrinsic, unique
+
Physical fiat currency
+
fungible, fractional, intrinsic, common
+
bank balance fiat currency
+
non-fungible, fractional, reference, unique
+
"mutual" collectible/art/property ownership
+
non-fungible, whole, intrinsic, unique
+
Physical work of fine art
+
non-fungible, whole, reference, unique
+
Registered property title
+
+ +| Name | Number | Description | +| ---- | ------ | ----------- | +| FUNGIBLE_COMMON | 0 | A fungible/common token.
Tokens of this type are interchangeable with one another, where any quantity of tokens has the same value as another equal quantity, if they are in the same class. Tokens share a single set of properties, and are not distinct from one another. Ownership is represented as a balance or quantity associated to a given account. Tokens may be divided into fractional tokens, within reasonable limits.

IWA taxonomy _fungible, fractional, intrinsic, common_ | +| NON_FUNGIBLE_UNIQUE | 1 | A non-fungible/unique token.
Tokens of this type are unique, and are not interchangeable with other tokens of the same type. Each token carries a serial number which is unique for that token, these tokens may have a different trade value for each individual token. The tokens are individually accounted and often carry additional unique properties. Tokens cannot be subdivided, and value is related to what the individual token represents.

IWA taxonomy _non-fungible, whole, reference, unique_ | + + + + + + + + + + diff --git a/documents/api/services/consensus_create_topic.md b/documents/api/services/consensus_create_topic.md new file mode 100644 index 00000000..9e2f2118 --- /dev/null +++ b/documents/api/services/consensus_create_topic.md @@ -0,0 +1,83 @@ +## Table of Contents + +- [consensus_create_topic.proto](#consensus_create_topic-proto) + - [ConsensusCreateTopicTransactionBody](#proto-ConsensusCreateTopicTransactionBody) + + + + + +

Top

+ +## consensus_create_topic.proto +# Create Topic +Create a new topic for the Hedera Consensus Service (HCS). + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ConsensusCreateTopicTransactionBody +Create a topic to accept and group consensus messages. + +If `autoRenewAccount` is specified, that account Key MUST also sign this +transaction.
+If `adminKey` is set, that Key MUST sign the transaction.
+On success, the resulting `TransactionReceipt` SHALL contain the newly +created `TopicId`. + +The `autoRenewPeriod` on a topic MUST be set to a value between +`MIN_AUTORENEW_PERIOD` (6999999 seconds/81 days) and +`MAX_AUTORENEW_PERIOD` (8000001 seconds/92 days).
+This also sets the initial expirationTime of the topic. + +If no `adminKey` is set on a topic + -`autoRenewAccount` SHALL NOT be set on the topic. + - A `deleteTopic` transaction SHALL fail. + - An `updateTopic` transaction that only extends the expirationTime MAY + succeed. + - Any other `updateTopic` transaction SHALL fail. + +If the topic expires and is not automatically renewed, the topic SHALL enter +the `EXPIRED` state. + - All transactions on the topic SHALL fail with TOPIC_EXPIRED + - Except an updateTopic() call that only extends the expirationTime. + - getTopicInfo() SHALL succeed, and show the topic is expired. +The topic SHALL remain in the `EXPIRED` state for a time determined by the +`AUTORENEW_GRACE_PERIOD` (configurable, originally 7 days).
+After the grace period, if the topic's expirationTime is not extended, the +topic SHALL be automatically deleted from state entirely, and cannot be +recovered or recreated. + +### Record Stream Effects +??? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| memo | [string](#string) | | A short memo for this topic.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8. | +| adminKey | [Key](#proto-Key) | | Access control for modification of the topic after it is created.

If this field is set, that key MUST sign this transaction.
If this field is set, that key MUST sign each future transaction to update or delete the topic.
An updateTopic transaction that _only_ extends the topic expirationTime (a "manual renewal" transaction) SHALL NOT require admin key signature.
A topic without an admin key SHALL be immutable, except for expiration and renewal.
If adminKey is not set, then `autoRenewAccount` SHALL NOT be set. | +| submitKey | [Key](#proto-Key) | | Access control for message submission to the topic.

If this field is set, that key MUST sign each consensus submit message for this topic.
If this field is not set then any account may submit a message on the topic, without restriction. | +| autoRenewPeriod | [Duration](#proto-Duration) | | The initial lifetime, in seconds, for the topic.
This is also the number of seconds for which the topic SHALL be automatically renewed upon expiring, if it has a valid auto-renew account.

This value MUST be set.
This value MUST be greater than the configured MIN_AUTORENEW_PERIOD.
This value MUST be less than the configured MAX_AUTORENEW_PERIOD. | +| autoRenewAccount | [AccountID](#proto-AccountID) | | The ID of the account to be charged renewal fees at the topic's expirationTime to extend the lifetime of the topic.

The topic lifetime SHALL be extended by the smallest of the following:

If this value is set, the referenced account MUST sign this transaction.
If this value is set, the `adminKey` field MUST also be set (though that key MAY not have any correlation to this account). | + + + + + + + + + + + + + + + diff --git a/documents/api/services/consensus_delete_topic.md b/documents/api/services/consensus_delete_topic.md new file mode 100644 index 00000000..f08f8b05 --- /dev/null +++ b/documents/api/services/consensus_delete_topic.md @@ -0,0 +1,58 @@ +## Table of Contents + +- [consensus_delete_topic.proto](#consensus_delete_topic-proto) + - [ConsensusDeleteTopicTransactionBody](#proto-ConsensusDeleteTopicTransactionBody) + + + + + +

Top

+ +## consensus_delete_topic.proto +# Delete Topic +Delete an existing topic from the Hedera Consensus Service (HCS). + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ConsensusDeleteTopicTransactionBody +Delete a topic. + +Once deleted, subsequent transactions or queries for that topic SHALL NOT +succeed.
+If adminKey is set on the topic, this transaction MUST be signed by that +key.
+If adminKey is not set on the topic, this transaction SHALL fail with a +response code of `UNAUTHORIZED`. A topic without an adminKey cannot be +deleted (but MAY expire). + +### Record Stream Effects +??? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| topicID | [TopicID](#proto-TopicID) | | Topic to be deleted. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/consensus_get_topic_info.md b/documents/api/services/consensus_get_topic_info.md new file mode 100644 index 00000000..42f5fd5f --- /dev/null +++ b/documents/api/services/consensus_get_topic_info.md @@ -0,0 +1,73 @@ +## Table of Contents + +- [consensus_get_topic_info.proto](#consensus_get_topic_info-proto) + - [ConsensusGetTopicInfoQuery](#proto-ConsensusGetTopicInfoQuery) + - [ConsensusGetTopicInfoResponse](#proto-ConsensusGetTopicInfoResponse) + + + + + +

Top

+ +## consensus_get_topic_info.proto +# Get Topic +Query a topic in the Hedera Consensus Service (HCS). + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ConsensusGetTopicInfoQuery +Retrieve the latest state of a topic. + +This method is unrestricted and allowed on any topic by any payer +account.
+A query for a deleted topic MAY succeed if the topic is within the +"autorenew grace period".
+A query for a topic removed from state SHALL NOT succeed. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.
This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither). | +| topicID | [TopicID](#proto-TopicID) | | A topic ID.

The network SHALL return information for this topic, if successful. | + + + + + + + + +### ConsensusGetTopicInfoResponse +Query response to describe the current state of a topic in the Hedera +Consensus Service(HCS). + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| topicID | [TopicID](#proto-TopicID) | | The ID of the topic requested in the query. | +| topicInfo | [ConsensusTopicInfo](#proto-ConsensusTopicInfo) | | Information describing the current state of the topic. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/consensus_service.md b/documents/api/services/consensus_service.md new file mode 100644 index 00000000..bd909abd --- /dev/null +++ b/documents/api/services/consensus_service.md @@ -0,0 +1,48 @@ +## Table of Contents + +- [consensus_service.proto](#consensus_service-proto) + - [ConsensusService](#proto-ConsensusService) + + + + + +

Top

+ +## consensus_service.proto +# Consensus Service API +GRPC service definitions for the Hedera Consensus Service (HCS). + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + + + + + + + +### ConsensusService +The Hedera Consensus Service (HCS) provides the ability for a Hashgraph to +provide aBFT consensus as to the order and validity of messages submitted to +a *topic*, as well as a *consensus timestamp* for those messages. + +| Method Name | Request Type | Response Type | Description | +| ----------- | ------------ | ------------- | ------------| +| createTopic | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Create an HCS topic.

On success, the resulting TransactionReceipt SHALL contain the newly created TopicId.
If the `adminKey` is set on the topic, this transaction MUST be signed by that key.
If the `adminKey` is _not_ set on the topic, this transaction MUST NOT set an `autoRenewAccount`. The new topic will be immutable and must be renewed manually.
If the `autoRenewAccount` is set on the topic, this transaction MUST be signed by that account.

The request body MUST be a [ConsensusCreateTopicTransactionBody](#proto.ConsensusCreateTopicTransactionBody) | +| updateTopic | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Update an HCS topic.

If the `adminKey` is not set on the topic, this transaction MUST extend the `expirationTime` and MUST NOT modify any other field.
If the `adminKey` is set on the topic, this transaction MUST be signed by that key.
If this transaction sets a new `adminKey`, this transaction MUST be signed by _both_ keys, the pre-update `adminKey` and the post-update `adminKey`.
If this transaction sets a new, non-null, `autoRenewAccount`, the newly set account MUST sign this transaction.

The request body MUST be a [ConsensusUpdateTopicTransactionBody](#proto.ConsensusUpdateTopicTransactionBody) | +| deleteTopic | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Delete an HCS topic.

If this transaction succeeds, all subsequent transactions referencing the deleted topic SHALL fail.
The `adminKey` MUST be set on the topic and this transaction MUST be signed by that key.
If the `adminKey` is not set on the topic, this transaction SHALL fail with a response code of `UNAUTHORIZED`. A topic without an `adminKey` cannot be deleted, but MAY expire.

The request body MUST be a [ConsensusDeleteTopicTransactionBody](#proto.ConsensusDeleteTopicTransactionBody) | +| submitMessage | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Submit a message to an HCS topic.

Valid and authorized messages on valid topics will be ordered by the consensus service, published in the block stream, and available to all subscribers on this topic via the mirror nodes.
If this transaction succeeds the resulting TransactionReceipt SHALL contain the latest topicSequenceNumber and topicRunningHash for the topic.
If the topic has a `submitKey` then that key MUST sign this transaction.

The request body MUST be a [ConsensusSubmitMessageTransactionBody](#proto.ConsensusSubmitMessageTransactionBody) | +| getTopicInfo | [Query](#proto-Query) | [Response](#proto-Response) | Retrieve the latest state of a topic. This method is unrestricted and allowed on any topic by any payer account.

The request body MUST be a [ConsensusGetTopicInfoQuery](#proto.ConsensusGetTopicInfoQuery)
The response body SHALL be a [ConsensusGetTopicInfoResponse](#proto.ConsensusGetTopicInfoResponse) | + + + + + diff --git a/documents/api/services/consensus_submit_message.md b/documents/api/services/consensus_submit_message.md new file mode 100644 index 00000000..a5012d54 --- /dev/null +++ b/documents/api/services/consensus_submit_message.md @@ -0,0 +1,86 @@ +## Table of Contents + +- [consensus_submit_message.proto](#consensus_submit_message-proto) + - [ConsensusMessageChunkInfo](#proto-ConsensusMessageChunkInfo) + - [ConsensusSubmitMessageTransactionBody](#proto-ConsensusSubmitMessageTransactionBody) + + + + + +

Top

+ +## consensus_submit_message.proto +# Submit Message +Submit a message to a topic via the Hedera Consensus Service (HCS). + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ConsensusMessageChunkInfo +Information describing the way in which a message submitted for consensus +is broken into multiple fragments to fit within network transaction +size limits. + +The use of multiple message fragments is RECOMMENDED for any message +greater than 4KiB in total size. + +### Record Stream Effects +??? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| initialTransactionID | [TransactionID](#proto-TransactionID) | | The TransactionID of the first chunk.

This MUST be set for every chunk in a fragmented message. | +| total | [int32](#int32) | | The total number of chunks in the message. | +| number | [int32](#int32) | | The sequence number (from 1 to total) of the current chunk in the message. | + + + + + + + + +### ConsensusSubmitMessageTransactionBody +Submit a message for consensus. +

+Valid and authorized messages on valid topics SHALL be ordered by the +consensus service, published in the block stream, and available to all +subscribers on this topic via the mirror nodes.
+If this transaction succeeds the resulting `TransactionReceipt` SHALL contain +the latest `topicSequenceNumber` and `topicRunningHash` for the topic.
+If the topic `submitKey` is set, and not an empty `KeyList`, then that key +MUST sign this transaction. + +### Record Stream Effects +??? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| topicID | [TopicID](#proto-TopicID) | | Topic to submit message to. | +| message | [bytes](#bytes) | | A message to be submitted.

This Transaction (including signatures) MUST be less than 6KiB.
Messages SHOULD be less than 4KiB. A "chunked" message MAY be submitted if a message larger than this is required. | +| chunkInfo | [ConsensusMessageChunkInfo](#proto-ConsensusMessageChunkInfo) | | Information for the current "chunk" in a fragmented message.

This value is REQUIRED if the full `message` is submitted in two or more fragments due to transaction size limits.
If the message is submitted in a single transaction, then this field SHOULD NOT be set. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/consensus_topic_info.md b/documents/api/services/consensus_topic_info.md new file mode 100644 index 00000000..e2d5b896 --- /dev/null +++ b/documents/api/services/consensus_topic_info.md @@ -0,0 +1,56 @@ +## Table of Contents + +- [consensus_topic_info.proto](#consensus_topic_info-proto) + - [ConsensusTopicInfo](#proto-ConsensusTopicInfo) + + + + + +

Top

+ +## consensus_topic_info.proto +# Topic Information +Query response describing a topic of the Hedera Consensus Service (HCS). + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ConsensusTopicInfo +A query response describing the current state of a topic for the Hedera +Consensus Service (HCS). + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| memo | [string](#string) | | A short description of this topic.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8. | +| runningHash | [bytes](#bytes) | | The latest running hash of the topic.

This 48-byte field is the output of a SHA-384 digest with input data determined by the current version of the running hash algorithm used by the network.
All new transactions SHALL use algorithm version `3`.
The bytes of each uint64 or uint32 encoded for the hash input MUST be in Big-Endian format.


If the algorithm version is '3', then the input data to the SHA-384 digest are, in order:
  1. The previous running hash of the topic (48 bytes)
  2. The `topicRunningHashVersion` (8 bytes)
  3. The payer account's shard (8 bytes)
  4. The payer account's realm (8 bytes)
  5. The payer account's number (8 bytes)
  6. The topic's shard (8 bytes)
  7. The topic's realm (8 bytes)
  8. The topic's number (8 bytes)
  9. The number of seconds since the epoch when the `ConsensusSubmitMessage` reached consensus (8 bytes)
  10. The number of nanoseconds within the second when the `ConsensusSubmitMessage` reached consensus (4 bytes)
  11. The `topicSequenceNumber` (8 bytes)
  12. The output of a SHA-384 digest of the message bytes from the `ConsensusSubmitMessage` (48 bytes)
| +| sequenceNumber | [uint64](#uint64) | | The current sequence number (starting at 1 for the first message) for messages on this topic. | +| expirationTime | [Timestamp](#proto-Timestamp) | | The expiration time for this topic, in seconds since the epoch.

For this purpose, `epoch` SHALL be the UNIX epoch with 0 at `1970-01-01T00:00:00.000Z`. | +| adminKey | [Key](#proto-Key) | | The key that MUST sign any transaction to update or modify this topic.

If this value is not set (null) then the topic CANNOT be deleted, modified, or updated. | +| submitKey | [Key](#proto-Key) | | The key that MUST sign any transaction to submit a message to this topic.

If this value is not set (null) then any account MAY submit messages to this topic. | +| autoRenewPeriod | [Duration](#proto-Duration) | | The duration, in seconds, to extend the `expirationTime` value when this topic is automatically renewed.

If the `autoRenewAccount` value for this topic is set to a valid account with sufficient HBAR balance to pay renewal fees when this topic expires, the system SHALL automatically renew this topic, extending the `expirationTime` value by the number of seconds described here.
If, however, the `autoRenewAccount` lacks sufficient HBAR balance to pay renewal fees when this topic expires, this topic SHALL be deleted after the time period specified in the `AUTORENEW_GRACE_PERIOD` configuration value. | +| autoRenewAccount | [AccountID](#proto-AccountID) | | An account that is designated to pay automatic renewal fees.

If this value is a valid account ID when this topic expires, this account SHALL be charged the renewal fees for this topic, if it holds sufficient HBAR balance. If the account does not hold sufficient HBAR balance to pay renewal fees when necessary, then this topic SHALL be deleted.
If this value is not set (null), or is not a valid account ID, when this topic expires, then this topic SHALL be deleted after the time period specified in the `AUTORENEW_GRACE_PERIOD` configuration value. | +| ledger_id | [bytes](#bytes) | | The ledger ID of the network that generated this response.

This is originally defined in HIP-198 and depends on network configuration. The current values, as of Q1 2024, are

Mainnet
0x00
Testnet
0x01
Previewnet
0x02
Undefined
0x03
Reserved
0x04
| + + + + + + + + + + + + + + + diff --git a/documents/api/services/consensus_update_topic.md b/documents/api/services/consensus_update_topic.md new file mode 100644 index 00000000..caaf1b89 --- /dev/null +++ b/documents/api/services/consensus_update_topic.md @@ -0,0 +1,60 @@ +## Table of Contents + +- [consensus_update_topic.proto](#consensus_update_topic-proto) + - [ConsensusUpdateTopicTransactionBody](#proto-ConsensusUpdateTopicTransactionBody) + + + + + +

Top

+ +## consensus_update_topic.proto +# Update Topic +Update a topic for the Hedera Consensus Service (HCS). + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ConsensusUpdateTopicTransactionBody +Update the fields of an existing HCS topic. + +The topicID field is REQUIRED. All other fields are OPTIONAL.
+Fields set on this transaction SHALL be updated.
+Fields _not_ set on this transaction SHALL NOT be updated. + +### Record Stream Effects +??? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| topicID | [TopicID](#proto-TopicID) | | The topic ID specifying the topic to update.

A topic with this ID MUST exist and MUST NOT be deleted.
This value is REQUIRED. | +| memo | [google.protobuf.StringValue](#google-protobuf-StringValue) | | An updated memo to be associated with this topic.

If this value is set, the current `adminKey` for the topic MUST sign this transaction.
This value, if set, SHALL be encoded UTF-8 and SHALL NOT exceed 100 bytes when so encoded. | +| expirationTime | [Timestamp](#proto-Timestamp) | | An updated expiration time for this topic, in seconds since the epoch.

For this purpose, `epoch` SHALL be the UNIX epoch with 0 at `1970-01-01T00:00:00.000Z`.
The expirationTime MUST NOT be greater than the sum of `MAX_AUTORENEW_PERIOD` and the actual consensus timestamp of this transaction.
If `adminKey` is unset for the _topic_, this transaction MUST NOT modify any other field. | +| adminKey | [Key](#proto-Key) | | Updated access control for modification of the topic.

If this field is set, that key and the previously set key MUST both sign this transaction.
If this value is an empty `KeyList`, the prior key MUST sign this transaction, and the topic SHALL be immutable after this transaction completes, except for expiration and renewal. | +| submitKey | [Key](#proto-Key) | | Updated access control for message submission to the topic.

If this value is set, the current `adminKey` for the topic MUST sign this transaction.
If this value is set to an empty `KeyList`, the `submitKey` for the topic will be unset after this transaction completes. When the `submitKey` is unset, any account may submit a message on the topic, without restriction. | +| autoRenewPeriod | [Duration](#proto-Duration) | | An updated value for the number of seconds by which the topic expiration will be automatically extended upon expiration, if it has a valid auto-renew account.

If this value is set, the current `adminKey` for the topic MUST sign this transaction.
This value, if set, MUST be greater than the configured MIN_AUTORENEW_PERIOD.
This value, if set, MUST be less than the configured MAX_AUTORENEW_PERIOD. | +| autoRenewAccount | [AccountID](#proto-AccountID) | | An updated ID for the account to be charged renewal fees at the topic's `expirationTime` to extend the lifetime of the topic.

If this value is set and not the "sentinel account", the referenced account MUST sign this transaction.
If this value is set, the current `adminKey` for the topic MUST sign this transaction.
If this value is set to the "sentinel account", which is `0.0.0`, the `autoRenewAccount` SHALL be removed from the topic. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/contract_call.md b/documents/api/services/contract_call.md new file mode 100644 index 00000000..54dff0e0 --- /dev/null +++ b/documents/api/services/contract_call.md @@ -0,0 +1,57 @@ +## Table of Contents + +- [contract_call.proto](#contract_call-proto) + - [ContractCallTransactionBody](#proto-ContractCallTransactionBody) + + + + + +

Top

+ +## contract_call.proto +# Contract Call +Transaction body for calls to a Smart Contract. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ContractCallTransactionBody +Call a function of a given smart contract, providing function parameter +inputs as needed. + +Resource ("gas") charges SHALL include all relevant fees incurred by the +contract execution, including any storage required.
+The total transaction fee SHALL incorporate all of the "gas" actually +consumed as well as the standard fees for transaction handling, data +transfers, signature verification, etc... + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| contractID | [ContractID](#proto-ContractID) | | The ID of a smart contract to call. | +| gas | [int64](#int64) | | A maximum limit to the amount of gas to use for this call.

The network SHALL charge the greater of the following, but SHALL NOT charge more than the value of this field.

  1. The actual gas consumed by the smart contract call.
  2. `80%` of this value.
The `80%` factor encourages reasonable estimation, while allowing for some overage to ensure successful execution. | +| amount | [int64](#int64) | | An amount of tinybar sent via this contract call.

If this is non-zero, the function MUST be `payable`. | +| functionParameters | [bytes](#bytes) | | The smart contract function to call, and the parameters to pass to that function.

These MUST be presented in EVM bytecode function call format. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/contract_call_local.md b/documents/api/services/contract_call_local.md new file mode 100644 index 00000000..1a092c39 --- /dev/null +++ b/documents/api/services/contract_call_local.md @@ -0,0 +1,89 @@ +## Table of Contents + +- [contract_call_local.proto](#contract_call_local-proto) + - [ContractCallLocalQuery](#proto-ContractCallLocalQuery) + - [ContractCallLocalResponse](#proto-ContractCallLocalResponse) + + + + + +

Top

+ +## contract_call_local.proto +# Local Contract Call +A Contract Call executed directly on the current node +(that is, without consensus). + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ContractCallLocalQuery +Call a query function of a given smart contract, providing function parameter +inputs as needed. + +This is performed locally on the particular node that the client is +communicating with. Executing the call locally is faster and less costly, +but imposes certain restrictions.
+The call MUST NOT change the state of the contract instance. This also +precludes any expenditure or transfer of HBAR or other tokens.
+The call SHALL NOT have a separate consensus timestamp.
+The call SHALL NOT generate a record nor a receipt.
+The response SHALL contain the output returned by the function call.
+ +This is generally useful for calling accessor functions which read (query) +state without changes or side effects. Any contract call that would use the +`STATICCALL` opcode MAY be called via contract call local with performance +and cost benefits. + +Unlike a ContractCall transaction, the node SHALL always consume the +_entire_ amount of offered "gas" in determining the fee for this query, so +accurate gas estimation is important. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.
This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither).

The payment MUST be sufficient for the base fees _and_ the full amount in the `gas` field. | +| contractID | [ContractID](#proto-ContractID) | | The ID of a smart contract to call. | +| gas | [int64](#int64) | | The amount of "gas" to use for this call.

This transaction SHALL consume all of the gas offered and charge the corresponding fee according to the current exchange rate between HBAR and "gas". | +| functionParameters | [bytes](#bytes) | | The smart contract function to call, and the parameters to pass to that function.

These SHALL be presented in EVM bytecode function call format. | +| maxResultSize | [int64](#int64) | | **Deprecated.** Do not use this field; it is ignored in the current software.

The maximum number of bytes that the result might include.
The call will fail if it would have returned more than this number of bytes. | +| sender_id | [AccountID](#proto-AccountID) | | The account that is the "sender" for this contract call.

If this is not set it SHALL be interpreted as the accountId from the associated transactionId.
If this is set then either the associated transaction or the foreign transaction data MUST be signed by the referenced account. | + + + + + + + + +### ContractCallLocalResponse +The response returned by a `ContractCallLocalQuery` transaction. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| functionResult | [ContractFunctionResult](#proto-ContractFunctionResult) | | The result(s) returned by the function call, if successful.

If the call failed this value SHALL be unset. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/contract_create.md b/documents/api/services/contract_create.md new file mode 100644 index 00000000..99a15f3e --- /dev/null +++ b/documents/api/services/contract_create.md @@ -0,0 +1,104 @@ +## Table of Contents + +- [contract_create.proto](#contract_create-proto) + - [ContractCreateTransactionBody](#proto-ContractCreateTransactionBody) + + + + + +

Top

+ +## contract_create.proto +# Smart Contract Create + +Create a new smart contract. + +## General Comments + - A smart contract normally enforces rules, so "the code is law".
+ For example, an ERC-20 contract prevents a transfer from being undone + without a signature by the recipient of the transfer. This characteristic + is generally true if the contract instance was created without a value + for the `adminKey` field. For some uses, however, it may be desirable to + create something like an ERC-20 contract that has a specific group of + trusted individuals who can act as a "supreme court" with the ability to + override the normal operation, when a sufficient number of them agree to + do so. If `adminKey` is set to a valid Key (which MAY be complex), then a + transaction that can change the state of the smart contract in arbitrary + ways MAY be signed with enough signatures to activate that Key. Such + transactions might reverse a transaction, change the code to close an + unexpected loophole, remove an exploit, or adjust outputs in ways not + covered by the code itself. The admin key MAY also be used to change the + autoRenewPeriod, and change the adminKey field itself (for example, to + remove that key after a suitable testing period). The API currently does + not implement all relevant capabilities. But it does allow the `adminKey` + field to be set and queried, and MAY implement further administrative + capability in future releases. + - The current API ignores shardID, realmID, and newRealmAdminKey, and + creates everything in shard 0 and realm 0. Future versions of the system + MAY support additional shards and realms. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ContractCreateTransactionBody +Create a new smart contract. + +If this transaction succeeds, the `ContractID` for the new smart contract +SHALL be set in the transaction receipt.
+The contract is defined by the initial bytecode (or `initcode`). The +`initcode` SHALL be stored either in a previously created file, or in the +transaction body itself for very small contracts. + +As part of contract creation, the constructor defined for the new smart +contract SHALL run with the parameters provided in the +`constructorParameters` field.
+The gas to "power" that constructor MUST be provided via the `gas` field, +and SHALL be charged to the payer for this transaction.
+If the contract _constructor_ stores information, it is charged gas for that +storage. There is a separate fee in HBAR to maintain that storage until the +expiration, and that fee SHALL be added to this transaction as part of the +_transaction fee_, rather than gas. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| fileID | [FileID](#proto-FileID) | | The source for the smart contract EVM bytecode.

The file containing the smart contract initcode. A copy of the contents SHALL be made and held as `bytes` in smart contract state.
The contract bytecode is limited in size only by the network file size limit. | +| initcode | [bytes](#bytes) | | The source for the smart contract EVM bytecode.

The bytes of the smart contract initcode. A copy of the contents SHALL be made and held as `bytes` in smart contract state.
This value is limited in length by the network transaction size limit. This entire transaction, including all fields and signatures, MUST be less than the network transaction size limit. | +| adminKey | [Key](#proto-Key) | | Access control for modification of the smart contract after it is created.

If this field is set, that key MUST sign this transaction.
If this field is set, that key MUST sign each future transaction to update or delete the contract.
An updateContract transaction that _only_ extends the topic expirationTime (a "manual renewal" transaction) SHALL NOT require admin key signature.

A contract without an admin key SHALL be immutable, except for expiration and renewal. | +| gas | [int64](#int64) | | A maximum limit to the amount of gas to use for the constructor call.

The network SHALL charge the greater of the following, but SHALL NOT charge more than the value of this field.

  1. The actual gas consumed by the smart contract constructor call.
  2. `80%` of this value.
The `80%` factor encourages reasonable estimation, while allowing for some overage to ensure successful execution. | +| initialBalance | [int64](#int64) | | The amount of HBAR to use as an initial balance for the account representing the new smart contract.

This value is presented in tinybar (10-8 HBAR).
The HBAR provided here will be withdrawn from the payer account that signed this transaction. | +| proxyAccountID | [AccountID](#proto-AccountID) | | **Deprecated.** Proxy account staking is handled via `staked_id`.

Former field to designate a proxy account for HBAR staking. This field MUST NOT be set. | +| autoRenewPeriod | [Duration](#proto-Duration) | | The initial lifetime, in seconds, for the smart contract, and the number of seconds for which the smart contract will be automatically renewed upon expiration.

This value MUST be set.
This value MUST be greater than the configured MIN_AUTORENEW_PERIOD.
This value MUST be less than the configured MAX_AUTORENEW_PERIOD.
| +| constructorParameters | [bytes](#bytes) | | An array of bytes containing the EVM-encoded parameters to pass to the smart contract constructor defined in the smart contract init code provided. | +| shardID | [ShardID](#proto-ShardID) | |

Review Question
Should this be deprecated?
It's never been used and probably never should be used...
Shard should be determined by the node the transaction is submitted to.

The shard in which to create the new smart contract.
This value is currently ignored. | +| realmID | [RealmID](#proto-RealmID) | |

Review Question
Should this be deprecated?
It's never been used and probably never should be used...
Realm should be determined by node and network parameters.

The shard/realm in which to create the new smart contract.
This value is currently ignored. | +| newRealmAdminKey | [Key](#proto-Key) | |

Review Question
Should this be deprecated?
It's never been used and probably never should be used...
If a realm is used, it must already exist; we shouldn't be creating it without a separate transaction.

This was intended to provide an admin key for any new realm created during the creation of the smart contract.
This value is currently ignored. a new realm SHALL NOT be created, regardless of the value of `realmID`. | +| memo | [string](#string) | | A short memo for this smart contract.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8. | +| max_automatic_token_associations | [int32](#int32) | | The maximum number of tokens that can be auto-associated with this smart contract.

If this is less than or equal to `used_auto_associations` (or 0), then this contract MUST manually associate with a token before transacting in that token.
Following HIP-904 This value may also be `-1` to indicate no limit.
This value MUST NOT be less than `-1`. | +| auto_renew_account_id | [AccountID](#proto-AccountID) | | The id of an account, in the same shard and realm as this smart contract, that has signed this transaction, allowing the network to use its balance, when needed, to automatically extend this contract's expiration time.

If this field is set, that key MUST sign this transaction.
If this field is set, then the network SHALL deduct the necessary fees from the designated auto renew account, if that account has sufficient balance. If the auto renew account does not have sufficient balance, then the fees for contract renewal SHALL be deducted from the HBAR balance held by the smart contract.
If this field is not set, then all renewal fees SHALL be deducted from the HBAR balance held by this contract. | +| staked_account_id | [AccountID](#proto-AccountID) | | An account ID.

This smart contract SHALL stake its HBAR via this account as proxy. | +| staked_node_id | [int64](#int64) | | The ID of a network node.

This smart contract SHALL stake its HBAR to this node.

Note: node IDs do fluctuate as node operators change. Most contracts are immutable, and a contract staking to an invalid node ID SHALL NOT participate in staking. Immutable contracts MAY find it more reliable to use a proxy account for staking (via `staked_account_id`) to enable updating the _effective_ staking node ID when necessary through updating the proxy account.
| +| decline_reward | [bool](#bool) | | A flag indicating that this smart contract declines to receive any reward for staking its HBAR balance to help secure the network.

If set to true, this smart contract SHALL NOT receive any reward for staking its HBAR balance to help secure the network, regardless of staking configuration, but MAY stake HBAR to support the network without reward. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/contract_delete.md b/documents/api/services/contract_delete.md new file mode 100644 index 00000000..b73185c2 --- /dev/null +++ b/documents/api/services/contract_delete.md @@ -0,0 +1,72 @@ +## Table of Contents + +- [contract_delete.proto](#contract_delete-proto) + - [ContractDeleteTransactionBody](#proto-ContractDeleteTransactionBody) + + + + + +

Top

+ +## contract_delete.proto +# Contract Delete +Delete a smart contract, transferring any remaining balance to a +designated account. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ContractDeleteTransactionBody +Delete a smart contract, and transfer any remaining HBAR balance to a +designated account. + +If this call succeeds then all subsequent calls to that smart +contract SHALL fail. + +### Requirements + - An account or smart contract MUST be designated to receive all remaining + account balances. + - The smart contract MUST have an admin key set. If the contract does not + have `admin_key` set, then this transaction SHALL fail and response code + `MODIFYING_IMMUTABLE_CONTRACT` SHALL be set. + - If `admin_key` is, or contains, an empty `KeyList` key, it SHALL be + treated the same as an admin key that is not set. + - The `Key` set for `admin_key` on the smart contract MUST have a valid + signature set on this transaction. + - The designated receiving account MAY have `receiver_sig_required` set. If + that field is set, the receiver account MUST also sign this transaction. + - The field `permanent_removal` MUST NOT be set. That field is reserved for + internal system use when purging the smart contract from state. Any user + transaction with that field set SHALL be rejected and a response code + `PERMANENT_REMOVAL_REQUIRES_SYSTEM_INITIATION` SHALL be set. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| contractID | [ContractID](#proto-ContractID) | | The id of the contract to be deleted.

This field is REQUIRED. | +| transferAccountID | [AccountID](#proto-AccountID) | | An Account ID recipient.

This account SHALL receive all HBAR and other tokens still owned by the contract that is removed. | +| transferContractID | [ContractID](#proto-ContractID) | | A contract ID recipient.

This contract SHALL receive all HBAR and other tokens still owned by the contract that is removed. | +| permanent_removal | [bool](#bool) | | A flag indicating that this transaction is "synthetic"; initiated by the node software.

The consensus nodes create such "synthetic" transactions to both to properly manage state changes and to communicate those changes to other systems via the Block Stream.
A user-initiated transaction MUST NOT set this flag. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/contract_get_bytecode.md b/documents/api/services/contract_get_bytecode.md new file mode 100644 index 00000000..a1b2840d --- /dev/null +++ b/documents/api/services/contract_get_bytecode.md @@ -0,0 +1,66 @@ +## Table of Contents + +- [contract_get_bytecode.proto](#contract_get_bytecode-proto) + - [ContractGetBytecodeQuery](#proto-ContractGetBytecodeQuery) + - [ContractGetBytecodeResponse](#proto-ContractGetBytecodeResponse) + + + + + +

Top

+ +## contract_get_bytecode.proto +# Get Contract Bytecode +A standard query to read the current bytecode for a smart contract. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ContractGetBytecodeQuery +A transaction body to request the current bytecode for a smart contract. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.
This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither). | +| contractID | [ContractID](#proto-ContractID) | | A smart contract ID.

The network SHALL return bytecode for this smart contract, if successful. | + + + + + + + + +### ContractGetBytecodeResponse +Information returned in response to a "get bytecode" query for a +smart contract. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| bytecode | [bytes](#bytes) | | The current bytecode of the requested smart contract. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/contract_get_info.md b/documents/api/services/contract_get_info.md new file mode 100644 index 00000000..887d316a --- /dev/null +++ b/documents/api/services/contract_get_info.md @@ -0,0 +1,97 @@ +## Table of Contents + +- [contract_get_info.proto](#contract_get_info-proto) + - [ContractGetInfoQuery](#proto-ContractGetInfoQuery) + - [ContractGetInfoResponse](#proto-ContractGetInfoResponse) + - [ContractGetInfoResponse.ContractInfo](#proto-ContractGetInfoResponse-ContractInfo) + + + + + +

Top

+ +## contract_get_info.proto +# Contract Get Info +A standard query to obtain detailed information about a smart contract. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ContractGetInfoQuery +Request detailed information about a smart contract. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.
This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither). | +| contractID | [ContractID](#proto-ContractID) | | A smart contract ID.

The network SHALL return information for this smart contract, if successful. | + + + + + + + + +### ContractGetInfoResponse +Information returned in response to a "get info" query for a smart contract. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| contractInfo | [ContractGetInfoResponse.ContractInfo](#proto-ContractGetInfoResponse-ContractInfo) | | The information, as requested, for a smart contract. A state proof MAY be generated for this value. | + + + + + + + + +### ContractGetInfoResponse.ContractInfo + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| contractID | [ContractID](#proto-ContractID) | | The ID of the smart contract requested in the query. | +| accountID | [AccountID](#proto-AccountID) | | The Account ID for the account entry associated with this smart contract. | +| contractAccountID | [string](#string) | | The "Solidity" form contract and account ID value that refers to this smart contract. | +| adminKey | [Key](#proto-Key) | | The key that MUST sign any transaction to update or modify this smart contract.

If this value is null, or is an empty `KeyList` then the contract CANNOT be deleted, modified, or updated, but MAY still expire. | +| expirationTime | [Timestamp](#proto-Timestamp) | | The point in time at which this contract will expire. | +| autoRenewPeriod | [Duration](#proto-Duration) | | The duration, in seconds, for which the contract lifetime will be automatically extended upon expiration, provide sufficient HBAR is available at that time to pay the renewal fee.
See `auto_renew_account_id` for additional conditions. | +| storage | [int64](#int64) | | The amount of storage used by this smart contract. | +| memo | [string](#string) | | A short description of this smart contract.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8. | +| balance | [uint64](#uint64) | | The current HBAR balance, in tinybar, of the smart contract account. | +| deleted | [bool](#bool) | | A flag indicating that this contract is deleted. | +| tokenRelationships | [TokenRelationship](#proto-TokenRelationship) | repeated | **Deprecated.** Because HIP-367, which allows an account to be associated to an unlimited number of tokens, it became necessary to only provide this information from a Mirror Node.
The list of tokens associated to this contract. | +| ledger_id | [bytes](#bytes) | | The ledger ID of the network that generated this response. + +This is originally defined in HIP-198 and depends on network configuration.
The current values, as of Q1 2024, are

Mainnet
0x00
Testnet
0x01
Previewnet
0x02
Undefined
0x03
Reserved
0x04
| +| auto_renew_account_id | [AccountID](#proto-AccountID) | | An account designated to pay the renewal fee upon automatic renewal of this contract.

If this is not set, or is set to an account with zero HBAR available, the HBAR balance of the contract, if available, SHALL be used to pay the renewal fee. | +| max_automatic_token_associations | [int32](#int32) | | The maximum number of tokens that the contract can be associated to automatically. | +| staking_info | [StakingInfo](#proto-StakingInfo) | | Staking information for this contract. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/contract_get_records.md b/documents/api/services/contract_get_records.md new file mode 100644 index 00000000..69fc32da --- /dev/null +++ b/documents/api/services/contract_get_records.md @@ -0,0 +1,72 @@ +## Table of Contents + +- [contract_get_records.proto](#contract_get_records-proto) + - [ContractGetRecordsQuery](#proto-ContractGetRecordsQuery) + - [ContractGetRecordsResponse](#proto-ContractGetRecordsResponse) + + + + + +

Top

+ +## contract_get_records.proto +# Get contract records +Deprecated query messages to read all recent contract transaction records. + +> REVIEW QUESTION +>> Can we delete this file and remove the related query entirely? +>> It appears it hasn't been supported for over 3½ years... + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ContractGetRecordsQuery +Deprecated and not supported after release `0.9.0`. +Request records of all transactions against the given contract in the last 25 hours. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.
This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither). | +| contractID | [ContractID](#proto-ContractID) | | A smart contract ID.

The network SHALL return information for this smart contract, if successful. | + + + + + + + + +### ContractGetRecordsResponse +Deprecated and not supported after release `0.9.0`. +Response with records of all transactions against the given contract in the last 25 hours. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| contractID | [ContractID](#proto-ContractID) | | A smart contract that this response describes. | +| records | [TransactionRecord](#proto-TransactionRecord) | repeated | A list of records, each with contractCreateResult or contractCallResult as its body | + + + + + + + + + + + + + + + diff --git a/documents/api/services/contract_types.md b/documents/api/services/contract_types.md new file mode 100644 index 00000000..f3961609 --- /dev/null +++ b/documents/api/services/contract_types.md @@ -0,0 +1,109 @@ +## Table of Contents + +- [contract_types.proto](#contract_types-proto) + - [ContractFunctionResult](#proto-ContractFunctionResult) + - [ContractLoginfo](#proto-ContractLoginfo) + - [ContractNonceInfo](#proto-ContractNonceInfo) + + + + + +

Top

+ +## contract_types.proto +# Contract Message Types +Message types used in contract transactions. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ContractFunctionResult +A contract function result.
+The result returned by a call to a smart contract function. This is part of +the response to a ContractCallLocal query, and is in the record for a +ContractCall. The ContractCreateInstance transaction record also carries a +function result, which is the results of the call to the constructor. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| contractID | [ContractID](#proto-ContractID) | | A contract identifier.
This identifies the smart contract that defines the function called. | +| contractCallResult | [bytes](#bytes) | | Result data from the function call.

This SHALL be encoded in EVM bytecode format. | +| errorMessage | [string](#string) | | Any error message produced by the contract call.

This SHALL be unset if the contract call succeeded. | +| bloom | [bytes](#bytes) | | A bloom filter produced by this contract call.
Ethereum uses this bloom filter to search for call results in the Ethereum block history. High false positive rates make the bloom filters quite limited value. | +| gasUsed | [uint64](#uint64) | | A quantity of "gas" used.
This represents the resource units expended to execute this contract call, and correlates to transaction costs. | +| logInfo | [ContractLoginfo](#proto-ContractLoginfo) | repeated | Any Log events produced by this contract call. | +| createdContractIDs | [ContractID](#proto-ContractID) | repeated | **Deprecated.** Replaced by values in transaction records to support `CREATE2` calls.

The list of smart contracts that were created by the function call.
The created ids will now _also_ be externalized through internal transaction records, where each record has its alias field populated with the new contract's EVM address.
This is needed for contracts created with CREATE2, which removes the trivial relationship between a new contract's Identifier and its Solidity address. | +| evm_address | [google.protobuf.BytesValue](#google-protobuf-BytesValue) | | A created contract address.
If the function created a new contract (e.g. `CREATE2`), this is the primary 20-byte EVM address for that contract.

Every contract SHALL have a "base" EVM address that is determined by its `shard.realm.num` contract ID.
This address is constructed as follows

  1. The first 4 bytes are the big-endian representation of the shard.
  2. The next 8 bytes are the big-endian representation of the realm.
  3. The final 8 bytes are the big-endian representation of the number.

Contracts created via `CREATE2` SHALL have an _additional_, primary, address that is derived from the EIP-1014 specification. This additional address SHALL NOT be directly related to the `shard.realm.num` contract ID.
It should be emphasized that Contracts created via a `CREATE2` call can also be referenced via the same "base" EVM address as described above. | +| gas | [int64](#int64) | | The amount of gas available for this call, sometimes referred to as the gasLimit.
This field SHALL NOT be populated when the associated `TransactionBody` in the block stream is a `ContractCreateTransactionBody` or a `ContractCallTransactionBody`. | +| amount | [int64](#int64) | | An amount, in tinybar, sent by this function call.
This SHALL be zero(0) if the function called is not `payable`.
This field SHALL NOT be populated when the associated `TransactionBody` in the block stream is a `ContractCreateTransactionBody` or a `ContractCallTransactionBody`. | +| functionParameters | [bytes](#bytes) | | The smart contract function to call, and the parameters to pass to that function.
These SHALL be presented in EVM bytecode function call format.
This field SHALL NOT be populated when the associated `TransactionBody` in the block stream is a `ContractCreateTransactionBody` or a `ContractCallTransactionBody`. | +| sender_id | [AccountID](#proto-AccountID) | | The account that was the "sender" for this contract call.
If this is not set it SHALL be read from the accountId in the transactionId for the contract call.
This field SHALL NOT be populated when the associated `TransactionBody` in the block stream is a `ContractCreateTransactionBody` or a `ContractCallTransactionBody`. | +| contract_nonces | [ContractNonceInfo](#proto-ContractNonceInfo) | repeated | A list of contract account nonce values.
This list SHALL contain a nonce value for each contract account modified as a result of this contract call. These nonce values SHALL be the value after the contract call is completed. | +| signer_nonce | [google.protobuf.Int64Value](#google-protobuf-Int64Value) | | A nonce value for the "signer account".
If the contract call updated the signer nonce for the signer account (i.e. by creating another contract), this field SHALL contain the updated value.
If the signer account nonce was not updated, this field SHALL be `null`. | + + + + + + + + +### ContractLoginfo +EVM log data for a contract call.
+The EVM log information produced by a smart contract function call. + +Each contract function call MAY return zero or more log events. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| contractID | [ContractID](#proto-ContractID) | | A contract identifier.
This refers to the contract that generated this log entry. | +| bloom | [bytes](#bytes) | | A bloom filter.
This filter applies to this log entry and indexes the contract log data in the full data of the Ethereum block.
EIP-7668 proposes to remove bloom filters as they are quite low value in practice and separate indexing services are more effective. | +| topic | [bytes](#bytes) | repeated | A list of the "topics" in this log entry.
The EVM permits up to 4 topics, each of which is 32 bytes (one EVM word).

The first "topic" is special, and MUST contain the keccak256 hash of the event signature, if the event is not anonymous. | +| data | [bytes](#bytes) | | Event data for this log entry.
This is binary data consisting of an arbitrary number of 256 bit (32 byte) words. The content of that data is determined by the smart contract code.
| + + + + + + + + +### ContractNonceInfo +A contract "nonce" reference.
+This connects a contract and its "nonce" value, and is primarily for use in +query responses. A "nonce" is short for "nonsense" and is usually a value +with no particular meaning. + +The nonce of a contract SHALL be incremented when that contract creates +another contract. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| contract_id | [ContractID](#proto-ContractID) | | A contract identifier.
This refers to the contract that holds this nonce value. | +| nonce | [int64](#int64) | | A "nonce" value. The current value of the nonce associated with the identified contract. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/contract_update.md b/documents/api/services/contract_update.md new file mode 100644 index 00000000..f796df96 --- /dev/null +++ b/documents/api/services/contract_update.md @@ -0,0 +1,74 @@ +## Table of Contents + +- [contract_update.proto](#contract_update-proto) + - [ContractUpdateTransactionBody](#proto-ContractUpdateTransactionBody) + + + + + +

Top

+ +## contract_update.proto +# Contract Update +Modify a smart contract. Any change other than updating the expiration time +requires that the contract be modifiable (has a valid `adminKey`) and that +the transaction be signed by the `adminKey` + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ContractUpdateTransactionBody +Modify the current state of a smart contract. + +### Requirements +- The `adminKey` MUST sign all contract update transactions except one + that only updates the `expirationTime`. +- A transaction that modifies any field other than `expirationTime` for + a contract without a valid `adminKey` set SHALL fail with response + code `MODIFYING_IMMUTABLE_CONTRACT`. +- Fields set to non-default values in this transaction SHALL be updated on + success. Fields not set to non-default values SHALL NOT be + updated on success. + +### Record Stream Effects +???? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| contractID | [ContractID](#proto-ContractID) | | The contact ID that identifies the smart contract to be updated.
This field MUST be set, and MUST NOT be a default ID (`0.0.0`). | +| expirationTime | [Timestamp](#proto-Timestamp) | | If set, modify the time at which this contract will expire.
An expired contract requires a rent payment to "renew" the contract. A transaction to update this field is how that rent payment is made.

This value MUST NOT be less than the current `expirationTime` of the contract. If this value is earlier than the current value, the transaction SHALL fail with response code `EXPIRATION_REDUCTION_NOT_ALLOWED`. | +| adminKey | [Key](#proto-Key) | | If set, modify the key that authorizes updates to the contract.

If this field is set to a valid Key, this key and the previously set key MUST both sign this transaction.
If this value is an empty `KeyList`, the prior key MUST sign this transaction, and the smart contract SHALL be immutable after this transaction completes, except for expiration and renewal.
If this value is not an empty `KeyList`, but does not contain any cryptographic keys, or is otherwise malformed, this transaction SHALL fail with response code `INVALID_ADMIN_KEY`. | +| proxyAccountID | [AccountID](#proto-AccountID) | | **Deprecated.** Replaced with `staked_id` alternatives. This field is unused and SHALL NOT modify the contract state.
The id of an account to which the contract is proxy staked | +| autoRenewPeriod | [Duration](#proto-Duration) | | If set, modify the duration added to expiration time by each auto-renewal to this value. | +| fileID | [FileID](#proto-FileID) | | **Deprecated.** This field is unused and SHALL NOT modify the contract state.
Previously, an ID of a file containing the bytecode of the Solidity transaction that created this contract. | +| memo | [string](#string) | | **Deprecated.** This value could not accurately distinguish unset or deliberately empty. memoWrapper should be used instead.
| +| memoWrapper | [google.protobuf.StringValue](#google-protobuf-StringValue) | | If set, modify the short memo for this smart contract.
This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8. | +| max_automatic_token_associations | [google.protobuf.Int32Value](#google-protobuf-Int32Value) | | If set, modify the maximum number of tokens that can be auto-associated with the contract.

If this is set and less than or equal to `used_auto_associations`, or 0, then this contract MUST manually associate with a token before transacting in that token.
This value MAY also be `-1` to indicate no limit.
This value MUST NOT be less than `-1`. | +| auto_renew_account_id | [AccountID](#proto-AccountID) | | If set, modify the account, in the same shard and realm as this smart contract, that has agreed to allow the network to use its balance, when needed, to automatically extend this contract's expiration time.

If this field is set to a non-default value, that Account MUST sign this transaction.
If this field is set to a default AccountID value (`0.0.0`), any pre-existing `auto_renew_account_id` value SHALL be removed on success. | +| staked_account_id | [AccountID](#proto-AccountID) | | An account identifier.
A staked account acts as a proxy, and this contract effectively nominates the same node as the identified account.

If set, modify this smart contract such that it SHALL stake its HBAR to the same node as the identified account.
If this field is set to a default AccountID value (`0.0.0`), any pre-existing `staked_account_id` value SHALL be removed on success. | +| staked_node_id | [int64](#int64) | | A node identifier.
A staked node identifier indicates the consensus node that this account nominates for staking.

If set, modify this smart contract such that it SHALL stake its HBAR to this node. If set to a the value `-1` any pre-existing `staked_node_id` value SHALL be removed on success.

Note: node IDs do fluctuate as node operators change. Most contracts are immutable, and a contract staking to an invalid node ID SHALL NOT participate in staking. Immutable contracts may find it more reliable to use a proxy account for staking (via `staked_account_id`) to enable updating the _effective_ staking node ID when necessary through updating the proxy account.
| +| decline_reward | [google.protobuf.BoolValue](#google-protobuf-BoolValue) | | A flag indicating if staking rewards are declined.
If set, modify the flag indicating if this contract declines to accept rewards for staking its HBAR to secure the network.

If set to true, this smart contract SHALL NOT receive any reward for staking its HBAR balance to help secure the network, regardless of staking configuration, but MAY stake HBAR to support the network without reward. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/crypto_add_live_hash.md b/documents/api/services/crypto_add_live_hash.md new file mode 100644 index 00000000..647f05a0 --- /dev/null +++ b/documents/api/services/crypto_add_live_hash.md @@ -0,0 +1,88 @@ +## Table of Contents + +- [crypto_add_live_hash.proto](#crypto_add_live_hash-proto) + - [CryptoAddLiveHashTransactionBody](#proto-CryptoAddLiveHashTransactionBody) + - [LiveHash](#proto-LiveHash) + + + + + +

Top

+ +## crypto_add_live_hash.proto +# Add Live Hash +Associate content to an account via a SHA-384 hash. + +> Important +>> This transaction is obsolete and not supported.
+>> Any transaction of this type that is submitted SHALL fail +>> with a `PRE_CHECK` result of `NOT_SUPPORTED`. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### CryptoAddLiveHashTransactionBody +Add a hash value to the ledger and associate it with an account. + +Create an entry in the ledger for a SHA-384 hash of some content, and +associate that with a specific account. This is sometimes used to associate +a credential or certificate with an account as a public record.
+The entry created is also associated with a list of keys, all of which +MUST sign this transaction.
+The account key for the associated account MUST sign this transaction.
+ +The live hash, once created, MAY be removed from the ledger with one +or more signatures. +- The account key of the account associated to the live hash. +- Any one key from the key list in the live hash entry. +- Any combination of keys from the key list in the live hash entry. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| liveHash | [LiveHash](#proto-LiveHash) | | A Live Hash to be added to the ledger and associated with the identified account. | + + + + + + + + +### LiveHash +A Live Hash value associating some item of content to an account. + +This message represents a desired entry in the ledger for a SHA-384 +hash of some content, an associated specific account, a list of authorized +keys, and a duration the live hash is "valid". + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| accountId | [AccountID](#proto-AccountID) | | An account associated via this live hash to the hashed content. | +| hash | [bytes](#bytes) | | A SHA-384 hash of some content that is associated to the account or account holder. | +| keys | [KeyList](#proto-KeyList) | | A list of keys, all of which MUST sign the transaction to add the live hash.
Any one of these keys may, however, remove the live hash to revoke the association. | +| duration | [Duration](#proto-Duration) | | A duration describing how long this Live Hash SHALL remain valid.
A Live Hash SHOULD NOT be relied upon after this duration has elapsed. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/crypto_approve_allowance.md b/documents/api/services/crypto_approve_allowance.md new file mode 100644 index 00000000..f402d071 --- /dev/null +++ b/documents/api/services/crypto_approve_allowance.md @@ -0,0 +1,165 @@ +## Table of Contents + +- [crypto_approve_allowance.proto](#crypto_approve_allowance-proto) + - [CryptoAllowance](#proto-CryptoAllowance) + - [CryptoApproveAllowanceTransactionBody](#proto-CryptoApproveAllowanceTransactionBody) + - [NftAllowance](#proto-NftAllowance) + - [TokenAllowance](#proto-TokenAllowance) + + + + + +

Top

+ +## crypto_approve_allowance.proto +# Approve Allowance +This transaction body provides a mechanism to add "allowance" entries +for an account. These allowances enable one account to spend or transfer +token balances (for fungible/common tokens), individual tokens (for +non-fungible/unique tokens), or all non-fungible tokens owned by the +account, now or in the future (if `approved_for_all` is set). + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### CryptoAllowance +An approved allowance of hbar transfers. +This message specifies one allowance for a single, unique, combination +of owner, spender, and amount. + +If `owner` is not set, the effective `owner` SHALL be the `payer` for the +enclosing transaction.
+The `spender` MUST be specified and MUST be a valid account.
+The `amount` MUST be a whole number, and SHOULD be greater than `0` unless +this allowance is intended to _remove_ a previously approved allowance. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| owner | [AccountID](#proto-AccountID) | | An owner account identifier.
This is the account identifier of the account granting an allowance for the `spender` to transfer tokens held by this account. | +| spender | [AccountID](#proto-AccountID) | | A spender account identifier.
This is the account identifier of the account permitted to transfer tokens held by the `owner`. | +| amount | [int64](#int64) | | An amount of tinybar (10-8 HBAR).
This is the amount of HBAR held by the `owner` that the `spender` is permitted to transfer.

This value MUST be a whole number.
This value MUST be greater than 0 to create a new allowance.
This value MAY be exactly `0` to _remove_ an existing allowance.
| + + + + + + + + +### CryptoApproveAllowanceTransactionBody +Create ("Approve") allowances for one account to transfer tokens owned +by a different account.
+An allowance permits a "spender" account to independently transfer tokens +owned by a separate "owner" account. Each such allowance permits spending +any amount, up to a specified limit, for fungible/common tokens; a single +specified non-fungible/unique token, or all non-fungible/unique tokens +of a particular token type held by the "owner" account. + +If the "owner" account is not specified for any allowance in this +transaction (the `owner` field is not set), the `payer` account for this +transaction SHALL be owner for that allowance.
+Each `owner` account specified in any allowance approved in this +transaction MUST sign this transaction.
+If the `amount` field for any fungible/common allowance in this +transaction is `0`, then that allowance SHOULD match an existing, +previously approved, allowance which SHALL be removed.
+There are three lists in this message. Each list MAY be empty, but +_at least one_ list MUST contain _at least one_ entry. + +Example for the `payer` rule.
+ - Given an account `0.0.X` that pays for this transaction, and owner + is not specified in an allowance of `200` HBAR to spender account + `0.0.Y`. At consensus the spender account `0.0.Y` will have a new + allowance to spend `200` HBAR from the balance of account `0.0.X`. + +### Record Stream Effects +???? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| cryptoAllowances | [CryptoAllowance](#proto-CryptoAllowance) | repeated | List of hbar allowances approved by the account owner.

This list MAY be empty, provided at least one other list is not empty. | +| nftAllowances | [NftAllowance](#proto-NftAllowance) | repeated | List of non-fungible token allowances approved by the account owner.

This list MAY be empty, provided at least one other list is not empty. | +| tokenAllowances | [TokenAllowance](#proto-TokenAllowance) | repeated | List of fungible token allowances approved by the account owner.

This list MAY be empty, provided at least one other list is not empty. | + + + + + + + + +### NftAllowance +An approved allowance of non-fungible tokens.
+This type of allowance may permit transfers for one or more individual +unique tokens, or may permit transfers for all unique tokens of the +specified type. + +If `owner` is not set, the effective `owner` SHALL be the `payer` for the +enclosing transaction.
+The `spender` MUST be specified and MUST be a valid account.
+If `approve_for_all` is set, then `serial_numbers` SHOULD be empty +and SHALL be ignored. +If `approve_for_all` is unset, then `serial_numbers` MUST NOT be empty. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| tokenId | [TokenID](#proto-TokenID) | | A token identifier.
This identifies the type of token the `spender` is permitted to transfer from the `owner`.

The identified token type MUST be a non-fungible/unique token. | +| owner | [AccountID](#proto-AccountID) | | An owner account identifier.
This is the account identifier of the account granting an allowance for the `spender` to transfer tokens held by this account. | +| spender | [AccountID](#proto-AccountID) | | A spender account identifier.
This is the account identifier of the account permitted to transfer tokens held by the `owner`. | +| serial_numbers | [int64](#int64) | repeated | A list of token serial numbers.
The list of serial numbers that the spender is permitted to transfer.

The `owner` MUST currently hold each token identified in this list. | +| approved_for_all | [google.protobuf.BoolValue](#google-protobuf-BoolValue) | | A flag indicating this allowance applies to all tokens of the specified (non-fungible/unique) type.

If true, the `spender` SHALL be permitted to transfer any or all of the `owner`'s tokens of the specified token type. This SHALL apply not only to currently owned tokens, but to all such tokens acquired in the future, unless the allowance is `delete`d. | +| delegating_spender | [AccountID](#proto-AccountID) | | A spender-owner account identifier.
This account identifier identifies a `spender` for whom an existing `approved_for_all` allowance was previously created. This enables an account with such broad access to grant allowances to transfer individual tokens from the original owner without involving that original owner.

If this is set, the account identified MUST sign this transaction, but the `owner` account MAY NOT sign this transaction.
If this is set, there MUST exist an active `approved_for_all` allowance from the `owner` for the `delegating_spender` to transfer all tokens of the type identified by the `tokenId` field.
If this value is set, the `approved_for_all` flag MUST be `false`. | + + + + + + + + +### TokenAllowance +An approved allowance of fungible/common token transfers. +This message specifies one allowance for a single, unique, combination +of token, owner, spender, and amount. + +If `owner` is not set, the effective `owner` SHALL be the `payer` for the +enclosing transaction.
+The `tokenId` MUST be specified and MUST be a valid +fungible/common token type.
+The `spender` MUST be specified and MUST be a valid account.
+The `amount` MUST be a whole number, and SHOULD be greater than `0` unless +this allowance is intended to _remove_ a previously approved allowance. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| tokenId | [TokenID](#proto-TokenID) | | A token identifier.
This identifies the type of token the `spender` is permitted to transfer from the `owner`.

The identified token type MUST be a fungible/common token. | +| owner | [AccountID](#proto-AccountID) | | An owner account identifier.
This is the account identifier of the account granting an allowance for the `spender` to transfer tokens held by this account. | +| spender | [AccountID](#proto-AccountID) | | A spender account identifier.
This is the account identifier of the account permitted to transfer tokens held by the `owner`. | +| amount | [int64](#int64) | | An amount of fractional tokens (10-decimals tokens).
This is the amount of tokens held by the `owner` that the `spender` is permitted to transfer.

This value MUST be a whole number.
This value MUST be greater than 0 to create a new allowance.
This value MAY be exactly `0` to _remove_ an existing allowance.
| + + + + + + + + + + + + + + + diff --git a/documents/api/services/crypto_create.md b/documents/api/services/crypto_create.md new file mode 100644 index 00000000..0e4841fd --- /dev/null +++ b/documents/api/services/crypto_create.md @@ -0,0 +1,71 @@ +## Table of Contents + +- [crypto_create.proto](#crypto_create-proto) + - [CryptoCreateTransactionBody](#proto-CryptoCreateTransactionBody) + + + + + +

Top

+ +## crypto_create.proto +# Crypto Create +Messages to create a new end-user account within the distributed ledger. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### CryptoCreateTransactionBody +Create a new account. + +If the auto_renew_account field is set, the key of the referenced account +MUST sign this transaction.
+Current limitations REQUIRE that `shardID` and `realmID` both MUST be `0`. +This is expected to change in the future. + +### Record Stream Effects +The account identifier for the newly created account SHALL be in the +transaction receipt. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| key | [Key](#proto-Key) | | The identifying key for this account. This key represents the account owner, and is required for most actions involving this account that do not modify the account itself. This key may also identify the account for smart contracts.

This field is REQUIRED. This `Key` MUST NOT be an empty `KeyList` and MUST contain at least one "primitive" (i.e. cryptographic) key value. | +| initialBalance | [uint64](#uint64) | | An amount, in tinybar, to deposit to the newly created account.

The deposited amount SHALL be debited to the "payer" account for this transaction. | +| proxyAccountID | [AccountID](#proto-AccountID) | | **Deprecated.** Use `staked_id` instead.
An account identifier for a staking proxy. | +| sendRecordThreshold | [uint64](#uint64) | | **Deprecated.** Removed prior to the first available history, and may be related to an early design dead-end.
An amount below which record stream records would not be created for a transaction that reduces this account balance. | +| receiveRecordThreshold | [uint64](#uint64) | | **Deprecated.** Removed prior to the first available history, and may be related to an early design dead-end.
An amount below which record stream records would not be created for a transaction that increases this account balance. | +| receiverSigRequired | [bool](#bool) | | A flag indicating the account holder must authorize all incoming token transfers.

If this flag is set then any transaction that would result in adding hbar or other tokens to this account balance MUST be signed by the identifying key of this account (that is, the `key` field).
If this flag is set, then the account key (`key` field) MUST sign this create transaction, in addition to the transaction payer. | +| autoRenewPeriod | [Duration](#proto-Duration) | | The duration between account automatic renewals.
All entities in state may be charged "rent" occasionally (typically every 90 days) to prevent unnecessary growth of the ledger. This value sets the interval between such events for this account.

If the account balance (in HBAR) is insufficient to pay the full renewal fee, the entire HBAR balance SHALL be consumed and the expiration for the account SHALL be extended as far as the available balance can support.
If the account HBAR balance is `0` when the account must be renewed, then the account SHALL be deleted, and subsequently removed from state. | +| shardID | [ShardID](#proto-ShardID) | | The shard in which this account is created

Currently, this MUST be `0`.
If the desired shard is `0`, this SHOULD NOT be set. | +| realmID | [RealmID](#proto-RealmID) | | The realm in which this account is created.

The shard number for this realm MUST match the value in `shardID`.
Currently, this MUST be `0` for both fields.
If the desired realm is `0.0`, this SHOULD NOT be set. | +| newRealmAdminKey | [Key](#proto-Key) | | **Deprecated.** If realmID is null, then this the admin key for the new realm that will be created

Should this be deprecated?
The "create realm" was never enabled, and probably should not be possible on account creation.
Added deprecated tag 2024-05 based on above. | +| memo | [string](#string) | | A short description of this Account.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8. | +| max_automatic_token_associations | [int32](#int32) | | A maximum number of tokens that can be auto-associated with this account.
By default this value is 0 for all accounts except for automatically created accounts (i.e smart contracts) which default to -1.

If this value is `0`, then this account MUST manually associate to a token before holding or transacting in that token.
This value MAY also be `-1` to indicate no limit.
This value MUST NOT be less than `-1`. | +| staked_account_id | [AccountID](#proto-AccountID) | | ID of the account to which this account is staking its balances.

If this account is not currently staking its balances, then this field, if set, MUST be the sentinel value of `0.0.0`. | +| staked_node_id | [int64](#int64) | | ID of the node this account is staked to.

If this account is not currently staking its balances, then this field, if set, SHALL be the sentinel value of `-1`.
Wallet software SHOULD surface staking issues to users and provide a simple mechanism to update staking to a new node ID in the event the prior staked node ID ceases to be valid. | +| decline_reward | [bool](#bool) | | A boolean indicating that this account has chosen to decline rewards for staking its balances.

This account MAY still stake its balances, but SHALL NOT receive reward payments for doing so, if this value is set. | +| alias | [bytes](#bytes) | | Bytes to be used as the account's alias.

This value, if set, MUST be one of the following values.

All aliases within the network MUST be unique. If this value matches an existing account alias, this `create` transaction SHALL fail.
If an account exists with a particular alias value, any transaction to transfer value _to_ that alias SHALL deposit the transferred value in the existing account, and SHALL NOT assess an account creation fee.
Once set, an account alias is immutable and MUST NOT be changed. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/crypto_delete.md b/documents/api/services/crypto_delete.md new file mode 100644 index 00000000..775fa126 --- /dev/null +++ b/documents/api/services/crypto_delete.md @@ -0,0 +1,62 @@ +## Table of Contents + +- [crypto_delete.proto](#crypto_delete-proto) + - [CryptoDeleteTransactionBody](#proto-CryptoDeleteTransactionBody) + + + + + +

Top

+ +## crypto_delete.proto +# Crypto Delete +Message to delete an account. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### CryptoDeleteTransactionBody +Delete an account.
+This will mark an account deleted, and transfer all tokens to a "sweep" +account. + +A deleted account SHALL NOT hold a balance in any token type.
+A deleted account SHALL remain in state until it expires.
+Transfers that would increase the balance of a deleted account +SHALL fail.
+A deleted account MAY be subject of a `cryptoUpdate` transaction to extend +its expiration.
+When a deleted account expires it SHALL be removed entirely, and SHALL NOT +be archived. + +### Record Stream Effects +??? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| transferAccountID | [AccountID](#proto-AccountID) | | An account identifier.

The identified account SHALL receive all tokens from the deleted account.
The identified account MUST sign this transaction.
If not set, the account to be deleted MUST NOT have a balance in any token, a balance in HBAR, or hold any NFT. | +| deleteAccountID | [AccountID](#proto-AccountID) | | An account identifier.

This account SHALL be deleted if this transaction succeeds.
This account SHOULD not hold any balance other than HBAR.
This account MUST sign this transaction.
This field MUST be set to a valid account identifier. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/crypto_delete_allowance.md b/documents/api/services/crypto_delete_allowance.md new file mode 100644 index 00000000..95f42843 --- /dev/null +++ b/documents/api/services/crypto_delete_allowance.md @@ -0,0 +1,90 @@ +## Table of Contents + +- [crypto_delete_allowance.proto](#crypto_delete_allowance-proto) + - [CryptoDeleteAllowanceTransactionBody](#proto-CryptoDeleteAllowanceTransactionBody) + - [NftRemoveAllowance](#proto-NftRemoveAllowance) + + + + + +

Top

+ +## crypto_delete_allowance.proto +# Crypto Delete Allowance +Delete one or more NFT allowances that permit transfer of tokens from +an "owner" account by a different, "spender", account. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### CryptoDeleteAllowanceTransactionBody +Delete one or more allowances.
+Given one or more, previously approved, allowances for non-fungible/unique +tokens to be transferred by a spending account from an owning account; +this transaction removes a specified set of those allowances. + +The owner account for each listed allowance MUST sign this transaction.
+Allowances for HBAR cannot be removed with this transaction. The owner +account MUST submit a new `cryptoApproveAllowance` transaction with the +amount set to `0` to "remove" that allowance.
+Allowances for fungible/common tokens cannot be removed with this +transaction. The owner account MUST submit a new `cryptoApproveAllowance` +transaction with the amount set to `0` to "remove" that allowance.
+ +### Record Stream Effects +??? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| nftAllowances | [NftRemoveAllowance](#proto-NftRemoveAllowance) | repeated | List of non-fungible/unique token allowances to remove.

This list MUST NOT be empty. | + + + + + + + + +### NftRemoveAllowance +A single allowance for one non-fungible/unique token. +This is specific to removal, and the allowance is identified for that +specific purpose. + +All fields in this message are REQUIRED. +The `serial_numbers` list MUST NOT be empty. +The combination of field values in this message MUST match existing +allowances for one or more individual non-fungible/unique tokens. + +> REVIEW NOTE +>> How does one remove an `approve_for_all` allowance? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| token_id | [TokenID](#proto-TokenID) | | A token identifier.

This MUST be a valid token identifier for a non-fungible/unique token type. | +| owner | [AccountID](#proto-AccountID) | | An `owner` account identifier.

This account MUST sign the transaction containing this message. | +| serial_numbers | [int64](#int64) | repeated | The list of serial numbers to remove allowances from.

This list MUST NOT be empty. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/crypto_delete_live_hash.md b/documents/api/services/crypto_delete_live_hash.md new file mode 100644 index 00000000..f18e875c --- /dev/null +++ b/documents/api/services/crypto_delete_live_hash.md @@ -0,0 +1,59 @@ +## Table of Contents + +- [crypto_delete_live_hash.proto](#crypto_delete_live_hash-proto) + - [CryptoDeleteLiveHashTransactionBody](#proto-CryptoDeleteLiveHashTransactionBody) + + + + + +

Top

+ +## crypto_delete_live_hash.proto +# Delete Live Hash +Dissociate a specific live hash from a specified account. + +> Important +>> This transaction is obsolete and not supported.
+>> Any transaction of this type that is submitted SHALL fail with a `PRE_CHECK` result +>> of `NOT_SUPPORTED`. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### CryptoDeleteLiveHashTransactionBody +Delete a specific live hash associated to a given account. + +This transaction MUST be signed by either the key of the associated account, +or at least one of the keys listed in the live hash. + +### Record Stream Effects +??? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| accountOfLiveHash | [AccountID](#proto-AccountID) | | An account associated to a live hash. | +| liveHashToDelete | [bytes](#bytes) | | The SHA-384 value of a specific live hash to delete. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/crypto_get_account_balance.md b/documents/api/services/crypto_get_account_balance.md new file mode 100644 index 00000000..b8e76c74 --- /dev/null +++ b/documents/api/services/crypto_get_account_balance.md @@ -0,0 +1,81 @@ +## Table of Contents + +- [crypto_get_account_balance.proto](#crypto_get_account_balance-proto) + - [CryptoGetAccountBalanceQuery](#proto-CryptoGetAccountBalanceQuery) + - [CryptoGetAccountBalanceResponse](#proto-CryptoGetAccountBalanceResponse) + + + + + +

Top

+ +## crypto_get_account_balance.proto +# Crypto Get Account Balance +Query request to obtain balance information for a single account. + +This query SHOULD NOT be used by client software, queries to a +Mirror Node provide more information at much lower cost. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### CryptoGetAccountBalanceQuery +Query to read the HBAR balance of an account or contract. + +This query SHALL return _only_ the HBAR balance for an account +or smart contract. Early releases of the network would return all +fungible/common token balances, but HIP-367 made it infeasible to +return all such balances. This query SHALL NOT return any information +beyond the current HBAR balance. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.
This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither). | +| accountID | [AccountID](#proto-AccountID) | | An account identifier.
This identifies an account for which the balance is requested.

Exactly one identifier MUST be provided. | +| contractID | [ContractID](#proto-ContractID) | | A smart contract identifier.
This identifies a smart contract for which the balance is requested.

Exactly one identifier MUST be provided. | + + + + + + + + +### CryptoGetAccountBalanceResponse +Response to a CryptoGetAccountBalanceQuery.
+ +This response SHALL contain only the information needed to +identify the query request and the actual HBAR balance of the +identified account or contract. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| accountID | [AccountID](#proto-AccountID) | | An account identifier.
This is the account ID queried.
The inclusion of the account queried is useful with state proofs, when needed to prove an account balance to a third party. | +| balance | [uint64](#uint64) | | A current account balance.
This is the current HBAR balance denominated in tinybar (10-8 HBAR). | +| tokenBalances | [TokenBalance](#proto-TokenBalance) | repeated | **Deprecated.** This field became infeasible to support after HIP-367 removed limits on the number of associated tokens.
A list of token balances for all tokens associated to the account.

This field was deprecated by HIP-367, which allowed an account to be associated to an unlimited number of tokens. This scale makes it more efficient for users to consult mirror nodes to review their token balances. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/crypto_get_account_records.md b/documents/api/services/crypto_get_account_records.md new file mode 100644 index 00000000..2464ba45 --- /dev/null +++ b/documents/api/services/crypto_get_account_records.md @@ -0,0 +1,73 @@ +## Table of Contents + +- [crypto_get_account_records.proto](#crypto_get_account_records-proto) + - [CryptoGetAccountRecordsQuery](#proto-CryptoGetAccountRecordsQuery) + - [CryptoGetAccountRecordsResponse](#proto-CryptoGetAccountRecordsResponse) + + + + + +

Top

+ +## crypto_get_account_records.proto +# Crypto Get Account Records +Messages for a query to retrieve recent transaction records involving a +specified account as effective `payer`.
+A "recent" transaction is typically one that reached consensus within +the previous three(`3`) minutes of _consensus_ time. Additionally, the +network only stores records in state when +`ledger.keepRecordsInState=true` was true during transaction handling. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### CryptoGetAccountRecordsQuery +Request records of all "recent" transactions for which the specified +account is the effective payer. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.
This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither). | +| accountID | [AccountID](#proto-AccountID) | | An account identifier.
This identifies the account to use when filtering the transaction record lists.

This field is REQUIRED. | + + + + + + + + +### CryptoGetAccountRecordsResponse +Return records of all "recent" transactions for which the specified +account is the effective payer. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| accountID | [AccountID](#proto-AccountID) | | An account identifier.
This identifies the account used when filtering the transaction record lists.

This field SHALL match the requested account identifier. | +| records | [TransactionRecord](#proto-TransactionRecord) | repeated | A list of records.

This list SHALL contain all available and "recent" records in which the account identified in the `accountID` field acted as effective payer. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/crypto_get_info.md b/documents/api/services/crypto_get_info.md new file mode 100644 index 00000000..18313585 --- /dev/null +++ b/documents/api/services/crypto_get_info.md @@ -0,0 +1,131 @@ +## Table of Contents + +- [crypto_get_info.proto](#crypto_get_info-proto) + - [CryptoGetInfoQuery](#proto-CryptoGetInfoQuery) + - [CryptoGetInfoResponse](#proto-CryptoGetInfoResponse) + - [CryptoGetInfoResponse.AccountInfo](#proto-CryptoGetInfoResponse-AccountInfo) + + + + + +

Top

+ +## crypto_get_info.proto +# Get Account Information +A standard query to inspect the full detail of an account. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### CryptoGetInfoQuery +A query to read information for an account. + +The returned information SHALL include balance.
+The returned information SHALL NOT include allowances.
+The returned information SHALL NOT include token relationships.
+The returned information SHALL NOT include account records. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.
This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither). | +| accountID | [AccountID](#proto-AccountID) | | The account ID for which information is requested | + + + + + + + + +### CryptoGetInfoResponse +Response when the client sends the node CryptoGetInfoQuery + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| accountInfo | [CryptoGetInfoResponse.AccountInfo](#proto-CryptoGetInfoResponse-AccountInfo) | | Details of the account.

A state proof MAY be generated for this field. | + + + + + + + + +### CryptoGetInfoResponse.AccountInfo +Information describing A single Account in the Hedera distributed ledger. + +#### Attributes +Each Account may have a unique three-part identifier, a Key, and one or +more token balances. Accounts also have an alias, which has multiple +forms, and may be set automatically. Several additional items are +associated with the Account to enable full functionality. + +#### Expiration +Accounts, as most items in the network, have an expiration time, recorded +as a `Timestamp`, and must be "renewed" for a small fee at expiration. +This helps to reduce the amount of inactive accounts retained in state. +Another account may be designated to pay any renewal fees and +automatically renew the account for (by default) 30-90 days at a time as +a means to optionally ensure important accounts remain active. + +### Staking +Accounts may participate in securing the network by "staking" the account +balances to a particular network node, and receive a portion of network +fees as a reward. An account may optionally decline these rewards but +still stake its balances. + +#### Transfer Restrictions +An account may optionally require that inbound transfer transactions be +signed by that account as receiver (in addition to any other signatures +required, including sender). + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| accountID | [AccountID](#proto-AccountID) | | a unique identifier for this account.

An account identifier, when assigned to this field, SHALL be of the form `shard.realm.number`. | +| contractAccountID | [string](#string) | | A Solidity ID.

This SHALL be populated if this account is a smart contract, and SHALL NOT be populated otherwise.
This SHALL be formatted as a string according to Solidity ID standards. | +| deleted | [bool](#bool) | | A boolean indicating that this account is deleted.

Any transaction involving a deleted account SHALL fail. | +| proxyAccountID | [AccountID](#proto-AccountID) | | **Deprecated.** Replaced by StakingInfo.
ID of the account to which this account is staking its balances. If this account is not currently staking its balances, then this field, if set, SHALL be the sentinel value of `0.0.0`. | +| proxyReceived | [int64](#int64) | | The total amount of tinybar proxy staked to this account. | +| key | [Key](#proto-Key) | | The key to be used to sign transactions from this account, if any.

This key SHALL NOT be set for hollow accounts until the account is finalized.
This key SHALL be set on all other accounts, except for certain immutable accounts (0.0.800 and 0.0.801) necessary for network function and otherwise secured by the governing council. | +| balance | [uint64](#uint64) | | The HBAR balance of this account, in tinybar (10-8 HBAR).

This value SHALL always be a whole number. | +| generateSendRecordThreshold | [uint64](#uint64) | | **Deprecated.** Obsolete and unused.
The threshold amount, in tinybars, at which a record was created for any transaction that decreased the balance of this account. | +| generateReceiveRecordThreshold | [uint64](#uint64) | | **Deprecated.** Obsolete and unused.
The threshold amount, in tinybars, at which a record was created for any transaction that increased the balance of this account. | +| receiverSigRequired | [bool](#bool) | | A boolean indicating that the account requires a receiver signature for inbound token transfer transactions.

If this value is `true` then a transaction to transfer tokens to this account SHALL NOT succeed unless this account has signed the transfer transaction. | +| expirationTime | [Timestamp](#proto-Timestamp) | | The current expiration time for this account.

This account SHALL be due standard renewal fees when the network consensus time exceeds this time.
If rent and expiration are enabled for the network, and automatic renewal is enabled for this account, renewal fees SHALL be charged after this time, and, if charged, the expiration time SHALL be extended for another renewal period.
This account MAY be expired and removed from state at any point after this time if not renewed.
An account holder MAY extend this time by submitting an account update transaction to modify expiration time, subject to the current maximum expiration time for the network. | +| autoRenewPeriod | [Duration](#proto-Duration) | | A duration to extend this account's expiration.

The network SHALL extend the account's expiration by this duration, if funds are available, upon automatic renewal.
This SHALL NOT apply if the account is already deleted upon expiration.
If this is not provided in an allowed range on account creation, the transaction SHALL fail with INVALID_AUTO_RENEWAL_PERIOD. The default values for the minimum period and maximum period are currently 30 days and 90 days, respectively. | +| liveHashes | [LiveHash](#proto-LiveHash) | repeated | All of the livehashes attached to the account (each of which is a hash along with the keys that authorized it and can delete it)

REVIEW NOTE
Should this be deprecated? Live hashes do not appear to be available any longer.
| +| tokenRelationships | [TokenRelationship](#proto-TokenRelationship) | repeated | **Deprecated.** As of `HIP-367`, which enabled unlimited token associations, the potential scale for this value requires that users consult a mirror node for this information. | +| memo | [string](#string) | | A short description of this account.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8. | +| ownedNfts | [int64](#int64) | | The total number of non-fungible/unique tokens owned by this account. | +| max_automatic_token_associations | [int32](#int32) | | The maximum number of tokens that can be auto-associated with the account.

If this is less than or equal to `used_auto_associations` (or 0), then this account MUST manually associate with a token before transacting in that token.
Following HIP-904 This value may also be `-1` to indicate no limit.
This value MUST NOT be less than `-1`. | +| alias | [bytes](#bytes) | | An account EVM alias.
This is a value used in some contexts to reference an account when the tripartite account identifier is not available.

This field, when set to a non-default value, is immutable and SHALL NOT be changed. | +| ledger_id | [bytes](#bytes) | | The ledger ID of the network that generated this response.
This is originally defined in `HIP-198` and depends on network configuration.
The current values, as of Q1 2024, are

Mainnet
0x00
Testnet
0x01
Previewnet
0x02
Undefined
0x03
Reserved
0x04
| +| ethereum_nonce | [int64](#int64) | | The ethereum transaction nonce associated with this account. | +| staking_info | [StakingInfo](#proto-StakingInfo) | | Staking information for this account. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/crypto_get_live_hash.md b/documents/api/services/crypto_get_live_hash.md new file mode 100644 index 00000000..c04ef9a9 --- /dev/null +++ b/documents/api/services/crypto_get_live_hash.md @@ -0,0 +1,76 @@ +## Table of Contents + +- [crypto_get_live_hash.proto](#crypto_get_live_hash-proto) + - [CryptoGetLiveHashQuery](#proto-CryptoGetLiveHashQuery) + - [CryptoGetLiveHashResponse](#proto-CryptoGetLiveHashResponse) + + + + + +

Top

+ +## crypto_get_live_hash.proto +# Get Live Hash +Standard query to inspect associations between content and accounts +via SHA-384 hashes. + +> Important +>> This query is obsolete and not supported.
+>> Any query of this type that is submitted SHALL fail with a `PRE_CHECK` +>> result of `NOT_SUPPORTED`. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### CryptoGetLiveHashQuery +Request detail for a specific live hash associated to a specific account. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.
This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither). | +| accountID | [AccountID](#proto-AccountID) | | An account ID.
The network SHALL return live hash information for this account, if successful. | +| hash | [bytes](#bytes) | | The specific SHA-384 live hash to inspect | + + + + + + + + +### CryptoGetLiveHashResponse +Return the full live hash associated to an account, if it is present. + +> Note that to generate a state proof of the _absence_ of a live hash from +> an account a transaction MUST retrieve a state proof of the `Account` +> with its list of live hashes. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| liveHash | [LiveHash](#proto-LiveHash) | | The requested live hash, if found. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/crypto_get_stakers.md b/documents/api/services/crypto_get_stakers.md new file mode 100644 index 00000000..eaab5bdf --- /dev/null +++ b/documents/api/services/crypto_get_stakers.md @@ -0,0 +1,106 @@ +## Table of Contents + +- [crypto_get_stakers.proto](#crypto_get_stakers-proto) + - [AllProxyStakers](#proto-AllProxyStakers) + - [CryptoGetStakersQuery](#proto-CryptoGetStakersQuery) + - [CryptoGetStakersResponse](#proto-CryptoGetStakersResponse) + - [ProxyStaker](#proto-ProxyStaker) + + + + + +

Top

+ +## crypto_get_stakers.proto +# Get Stakers +Query all of the accounts proxy staking _to_ a specified account. + +> Important +>> This query is obsolete and not supported.
+>> Any query of this type that is submitted SHALL fail with a `PRE_CHECK` +>> result of `NOT_SUPPORTED`. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### AllProxyStakers +All of the accounts proxy staking to a given account, and the amounts proxy +staked + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| accountID | [AccountID](#proto-AccountID) | | The Account ID that is being proxy staked to | +| proxyStaker | [ProxyStaker](#proto-ProxyStaker) | repeated | Each of the proxy staking accounts, and the amount they are proxy staking | + + + + + + + + +### CryptoGetStakersQuery +Get all the accounts that are proxy staking to this account. For each of +them, give the amount currently staked. This was never implemented. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.
This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither). | +| accountID | [AccountID](#proto-AccountID) | | The Account ID for which the records should be retrieved | + + + + + + + + +### CryptoGetStakersResponse +Response when the client sends the node CryptoGetStakersQuery + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| stakers | [AllProxyStakers](#proto-AllProxyStakers) | | List of accounts proxy staking to this account, and the amount each is currently proxy staking | + + + + + + + + +### ProxyStaker +information about a single account that is proxy staking + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| accountID | [AccountID](#proto-AccountID) | | The Account ID that is proxy staking | +| amount | [int64](#int64) | | The number of hbars that are currently proxy staked | + + + + + + + + + + + + + + + diff --git a/documents/api/services/crypto_service.md b/documents/api/services/crypto_service.md new file mode 100644 index 00000000..555d7ff8 --- /dev/null +++ b/documents/api/services/crypto_service.md @@ -0,0 +1,66 @@ +## Table of Contents + +- [crypto_service.proto](#crypto_service-proto) + - [CryptoService](#proto-CryptoService) + + + + + +

Top

+ +## crypto_service.proto +# Crypto Service +A service defining transactions and queries related to accounts. + +This includes transactions for HBAR transfers and balance queries as well as +transactions to manage "allowances" which permit a third party to spend a +portion of the HBAR balance in an account.
+Basic account, record, and receipt queries are also defined in this service. + +Transactions and queries relating to tokens _other than HBAR_ are defined +in the Token Service. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + + + + + + + +### CryptoService +Transactions and queries for the Hedera Crypto Service. + +The following queries are permanently removed. +getStakersByAccountID, getFastTransactionRecord + +| Method Name | Request Type | Response Type | Description | +| ----------- | ------------ | ------------- | ------------| +| createAccount | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Create a new account by submitting the transaction | +| updateAccount | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Update an account by submitting the transaction | +| cryptoTransfer | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Initiate a transfer by submitting the transaction | +| cryptoDelete | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Delete an account by submitting the transaction | +| approveAllowances | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Add one or more approved allowances for spenders to transfer the paying account's hbar or tokens. | +| deleteAllowances | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Delete one or more of the specific approved NFT serial numbers on an owner account. | +| addLiveHash | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Add a livehash
Important
This transaction is obsolete, not supported, and SHALL fail with a pre-check result of `NOT_SUPPORTED`.
| +| deleteLiveHash | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Delete a livehash
Important
This transaction is obsolete, not supported, and SHALL fail with a pre-check result of `NOT_SUPPORTED`.
| +| getLiveHash | [Query](#proto-Query) | [Response](#proto-Response) | Retrieve a livehash for an account
Important
This query is obsolete, not supported, and SHALL fail with a pre-check result of `NOT_SUPPORTED`.
| +| getAccountRecords | [Query](#proto-Query) | [Response](#proto-Response) | Return all transactions in the last 180s of consensus time for which the given account was the effective payer **and** network property `ledger.keepRecordsInState` was `true`. | +| cryptoGetBalance | [Query](#proto-Query) | [Response](#proto-Response) | Retrieve the balance of an account | +| getAccountInfo | [Query](#proto-Query) | [Response](#proto-Response) | Retrieve the metadata of an account | +| getTransactionReceipts | [Query](#proto-Query) | [Response](#proto-Response) | Retrieve the latest receipt for a transaction that is either awaiting consensus, or reached consensus in the last 180 seconds | +| getTxRecordByTxID | [Query](#proto-Query) | [Response](#proto-Response) | Retrieve the record of a transaction that is either awaiting consensus, or reached consensus in the last 180 seconds | + + + + + diff --git a/documents/api/services/crypto_transfer.md b/documents/api/services/crypto_transfer.md new file mode 100644 index 00000000..2c22271c --- /dev/null +++ b/documents/api/services/crypto_transfer.md @@ -0,0 +1,84 @@ +## Table of Contents + +- [crypto_transfer.proto](#crypto_transfer-proto) + - [CryptoTransferTransactionBody](#proto-CryptoTransferTransactionBody) + + + + + +

Top

+ +## crypto_transfer.proto +# Crypto Transfer +Transaction to transfer HBAR between accounts, or between accounts and +smart contracts. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### CryptoTransferTransactionBody +Transfer HBAR and/or other tokens among two or more accounts and/or smart +contracts. + +Transfers of HBAR or fungible/common tokens in this transaction are +structured as a "double-entry" transfer list which debits one or more +accounts, and separately credits one or more accounts. Each such transfer +list may specify up to 10 individual credits or debits.
+Transfers of non-fungible/unique tokens in this transaction are +structured as a "single-entry" transfer list, which both debits one account +and credits another account in a single entry. + +At least one transfer MUST be present, this MAY be an HBAR transfer in +`transfers`, or MAY be a token transfer in `tokenTransfers`.
+Either `transfers` or `tokenTransfers` MAY be unset, provided the other +is set and not empty.
+If any one account with a debit in any transfer list holds insufficient +balance to complete the transfer, the entire transaction SHALL fail, and +all transfers SHALL NOT be completed.
+If any one account that is _sending_ an individual non-fungible/unique (NFT) +token does not currently hold that unique NFT, the entire transaction SHALL +FAIL, and all transfers SHALL NOT be completed. +The transaction fee SHALL be charged for a transaction that fails due to +insufficient balance or not holding the NFT to be transferred.
+Each account with any debit amounts in any transfer list MUST sign this +transaction.
+Each account with any credit amounts in any transfer list that also has the +`receiverSigRequired` flag set MUST sign this transaction. + +### Record Stream Effects +All debits and credits completed by this transaction SHALL be included in +the transaction record transfer list.
+Multiple fungible/common debits from one account, or credits to one account, +MAY be consolidated to a single debit or credit entry in the +transaction record.
+Multiple non-fungible/unique transfers SHALL NOT be consolidated in the +transaction record. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| transfers | [TransferList](#proto-TransferList) | | A list of HBAR transfers.

Each transfer in this list MUST be denominated in tinybar. | +| tokenTransfers | [TokenTransferList](#proto-TokenTransferList) | repeated | One or more lists of token transfers.

This list MUST NOT contain more than 10 entries.
If custom fees must be charged, the fee SHALL be assessed against the effective "payer" for this transaction.
If the effective "payer" for this transaction lacks sufficient balance to pay custom fees assessed, the entire transaction SHALL fail with a response code `INSUFFICIENT_PAYER_BALANCE_FOR_CUSTOM_FEE`. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/crypto_update.md b/documents/api/services/crypto_update.md new file mode 100644 index 00000000..2b26daff --- /dev/null +++ b/documents/api/services/crypto_update.md @@ -0,0 +1,86 @@ +## Table of Contents + +- [crypto_update.proto](#crypto_update-proto) + - [CryptoUpdateTransactionBody](#proto-CryptoUpdateTransactionBody) + + + + + +

Top

+ +## crypto_update.proto +# Crypto Update +Modify a single account. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### CryptoUpdateTransactionBody +Modify the current state of an account. + +### Requirements +- The `key` for this account MUST sign all account update transactions. +- If the `key` field is set for this transaction, then _both_ the current + `key` and the new `key` MUST sign this transaction, for security and to + prevent setting the `key` field to an invalid value. +- If the `auto_renew_account` field is set for this transaction, the account + identified in that field MUST sign this transaction. +- Fields set to non-default values in this transaction SHALL be updated on + success. Fields not set to non-default values SHALL NOT be + updated on success. +- All fields that may be modified in this transaction SHALL have a + default value of unset (a.k.a. `null`). + +### Record Stream Effects +???? + +NOTE: Seven deprecated fields should probably be removed and the + field names reserved. +reserved 4,5,6,7,10,11,12 +Also, the `receiverSigRequiredField` oneOf should be removed +around `receiverSigRequiredWrapper` and the field renamed +(both actions are "safe" in protobuf) to `receiver_signature_required`. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| accountIDToUpdate | [AccountID](#proto-AccountID) | | An account identifier.
This identifies the account which is to be modified in this transaction.

This field is REQUIRED. | +| key | [Key](#proto-Key) | | An account key.
This may be a "primitive" key (a singly cryptographic key), or a composite key.

If set, this key MUST be a valid key.
If set, the previous key and new key MUST both sign this transaction. | +| proxyAccountID | [AccountID](#proto-AccountID) | | **Deprecated.** Removed in favor of the `staked_id` oneOf.
An account identifier for a "proxy" account. This account's HBAR are staked to a node selected by the proxy account. | +| proxyFraction | [int32](#int32) | | **Deprecated.** Removed prior to the first available history.
A fraction to split staking rewards between this account and the proxy account. | +| sendRecordThreshold | [uint64](#uint64) | | **Deprecated.** Removed prior to the first available history, and may be related to an early design dead-end.
The new threshold amount (in tinybars) for which an account record is created for any send/withdraw transaction | +| sendRecordThresholdWrapper | [google.protobuf.UInt64Value](#google-protobuf-UInt64Value) | | **Deprecated.** Removed prior to the first available history, and may be related to an early design dead-end.
The new threshold amount (in tinybars) for which an account record is created for any send/withdraw transaction | +| receiveRecordThreshold | [uint64](#uint64) | | **Deprecated.** Removed prior to the first available history, and may be related to an early design dead-end.
The new threshold amount (in tinybars) for which an account record is created for any receive/deposit transaction. | +| receiveRecordThresholdWrapper | [google.protobuf.UInt64Value](#google-protobuf-UInt64Value) | | **Deprecated.** Removed prior to the first available history, and may be related to an early design dead-end.
The new threshold amount (in tinybars) for which an account record is created for any receive/deposit transaction. | +| autoRenewPeriod | [Duration](#proto-Duration) | | A duration to extend account expiration.
An amount of time, in seconds, to extend the expiration date for this account when _automatically_ renewed.

This duration MUST be between the current configured minimum and maximum values defined for the network.
This duration SHALL be applied only when _automatically_ extending the account expiration. | +| expirationTime | [Timestamp](#proto-Timestamp) | | A new account expiration time, in seconds since the epoch.

For this purpose, `epoch` SHALL be the UNIX epoch with 0 at `1970-01-01T00:00:00.000Z`.
If set, this value MUST be later than the current consensus time.
If set, this value MUST be earlier than the current consensus time extended by the current maximum expiration time configured for the network. | +| receiverSigRequired | [bool](#bool) | | **Deprecated.** Removed to distinguish between unset and a default value.
Do NOT use this field to set a false value because the server cannot distinguish from the default value. Use receiverSigRequiredWrapper field for this purpose. | +| receiverSigRequiredWrapper | [google.protobuf.BoolValue](#google-protobuf-BoolValue) | | A flag indicating the account holder must authorize all incoming token transfers.

If this flag is set then any transaction that would result in adding hbar or other tokens to this account balance MUST be signed by the identifying key of this account (that is, the `key` field). | +| memo | [google.protobuf.StringValue](#google-protobuf-StringValue) | | A short description of this Account.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8. | +| max_automatic_token_associations | [google.protobuf.Int32Value](#google-protobuf-Int32Value) | | A maximum number of tokens that can be auto-associated with this account.
By default this value is 0 for all accounts except for automatically created accounts (i.e smart contracts) which default to -1.

If this value is `0`, then this account MUST manually associate to a token before holding or transacting in that token.
This value MAY also be `-1` to indicate no limit.
If set, this value MUST NOT be less than `-1`.
| +| staked_account_id | [AccountID](#proto-AccountID) | | ID of the account to which this account is staking its balances.

If this account is not currently staking its balances, then this field, if set, MUST be the sentinel value of `0.0.0`. | +| staked_node_id | [int64](#int64) | | ID of the node this account is staked to.

If this account is not currently staking its balances, then this field, if set, SHALL be the sentinel value of `-1`.
Wallet software SHOULD surface staking issues to users and provide a simple mechanism to update staking to a new node ID in the event the prior staked node ID ceases to be valid. | +| decline_reward | [google.protobuf.BoolValue](#google-protobuf-BoolValue) | | A boolean indicating that this account has chosen to decline rewards for staking its balances.

This account MAY still stake its balances, but SHALL NOT receive reward payments for doing so, if this value is set, and `true`. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/custom_fees.md b/documents/api/services/custom_fees.md new file mode 100644 index 00000000..5388a350 --- /dev/null +++ b/documents/api/services/custom_fees.md @@ -0,0 +1,217 @@ +## Table of Contents + +- [custom_fees.proto](#custom_fees-proto) + - [AssessedCustomFee](#proto-AssessedCustomFee) + - [CustomFee](#proto-CustomFee) + - [FixedFee](#proto-FixedFee) + - [FractionalFee](#proto-FractionalFee) + - [RoyaltyFee](#proto-RoyaltyFee) + + + + + +

Top

+ +## custom_fees.proto +# Custom Fees +Fees defined by token creators that are charged as part of each +transfer of that token type. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### AssessedCustomFee +Description of a transfer added to a `cryptoTransfer` transaction that +satisfies custom fee requirements. + +It is important to note that this is not the actual transfer. The transfer +of value SHALL be merged into the original transaction to minimize the +number of actual transfers. This descriptor presents the fee assessed +separately in the record stream so that the details of the fee assessed +are not hidden in this process. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| amount | [int64](#int64) | | An amount of tokens assessed for this custom fee.

This shall be expressed in units of 10-decimals tokens. | +| token_id | [TokenID](#proto-TokenID) | | The token transferred to satisfy this fee.

If the token transferred is HBAR, this field SHALL NOT be set. | +| fee_collector_account_id | [AccountID](#proto-AccountID) | | An account that received the fee assessed.

This SHALL NOT be the sender or receiver of the original cryptoTransfer transaction. | +| effective_payer_account_id | [AccountID](#proto-AccountID) | repeated | An account that provided the tokens assessed as a fee.

This SHALL be the account that _would have_ had a higher balance absent the fee. In most cases this SHALL be the `sender`, but some _fractional_ fees reduce the amount transferred, and in those cases the `receiver` SHALL be the effective payer for the fee.
There are currently no situations where a third party pays a custom fee. This MAY change in a future release. | + + + + + + + + +### CustomFee +A transfer fee to assess during a CryptoTransfer.
+This fee applies to transactions that transfer units of the token to +which the fee is attached. A custom fee may be either fixed or fractional, +and must specify a fee collector account to receive the assessed fees. + +Custom fees MUST be greater than zero (0). + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| fixed_fee | [FixedFee](#proto-FixedFee) | | A fixed fee to be charged to the `sender` for every token transfer.

This type of fee MAY be defined for any token type.
This type of fee MAY be more consistent and reliable than other types. | +| fractional_fee | [FractionalFee](#proto-FractionalFee) | | A fee defined as a fraction of the tokens transferred.

This type of fee MUST NOT be defined for a non-fungible/unique token type.
This fee MAY be charged to either sender, as an increase to the amount sent, or receiver, as a reduction to the amount received. | +| royalty_fee | [RoyaltyFee](#proto-RoyaltyFee) | | A fee charged as royalty for any transfer of a non-fungible/unique token.

This type of fee MUST NOT be defined for a fungible/common token type. | +| fee_collector_account_id | [AccountID](#proto-AccountID) | | The account to receive the custom fee. | +| all_collectors_are_exempt | [bool](#bool) | | Flag indicating to exempt all custom fee collector accounts for this token type from paying this custom fee when sending tokens.

The treasury account for a token, and the account identified by the `fee_collector_account_id` field of this `CustomFee` are always exempt from this custom fee to avoid redundant and unnecessary transfers. If this value is `true` then the account(s) identified in `fee_collector_account_id` for _all_ custom fee definitions for this token type SHALL also be exempt from this custom fee. This behavior is specified in HIP-573. | + + + + + + + + +### FixedFee +A fixed fee to assess for each token transfer, regardless of the +amount transferred.
+This fee type describes a fixed fee for each transfer of a token type. + +The fee SHALL be charged to the `sender` for the token transfer +transaction.
+This fee MAY be assessed in HBAR, the token type transferred, or any +other token type, as determined by the `denominating_token_id` field. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| amount | [int64](#int64) | | The amount to assess for each transfer.

This value MUST be greater than `0`.
This amount is expressed in units of 10-decimals tokens. | +| denominating_token_id | [TokenID](#proto-TokenID) | | The token type used to pay the assessed fee.

If this is unset, the fee SHALL be assessed in HBAR.
If this is set, the fee SHALL be assessed in the token identified. This MAY be any token type. Custom fees assessed in other token types are more likely to fail, however, and it is RECOMMENDED that token creators denominate custom fees in the transferred token, HBAR, or well documented and closely related token types.
If this value is set to `0.0.0` in the `tokenCreate` transaction, it SHALL be replaced with the `TokenID` of the newly created token. | + + + + + + + + +### FractionalFee +A descriptor for a fee based on a portion of the tokens transferred. + +This fee option describes fees as a fraction of the amount of +fungible/common token(s) transferred. The fee also describes a minimum +and maximum amount, both of which are OPTIONAL. + +This type of fee SHALL be assessed only for fungible/common tokens.
+This type of fee MUST NOT be defined for a non-fungible/unique +token type.
+This fee SHALL be paid with the same type of tokens as those +transferred.
+The fee MAY be subtracted from the transferred tokens, or MAY be assessed +to the sender in addition to the tokens actually transferred, based on +the `net_of_transfers` field. + +When a single transaction sends tokens from one sender to multiple +recipients, and the `net_of_transfers` flag is false, the network +SHALL attempt to evenly assess the total fee across all recipients +proportionally. This may be inexact and, particularly when there are +large differences between recipients, MAY result in small deviations +from an ideal "fair" distribution.
+If the sender lacks sufficient tokens to pay fees, or the assessment +of custom fees reduces the net amount transferred to or below zero, +the transaction MAY fail due to insufficient funds to pay all fees. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| fractional_amount | [Fraction](#proto-Fraction) | | A Fraction of the transferred tokens to assess as a fee.
This value MUST be less than or equal to one.
This value MUST be greater than zero. | +| minimum_amount | [int64](#int64) | | A minimum fee to charge, in units of 10-decimals tokens.

This value is OPTIONAL, with a default of `0` indicating no minimum.
If set, this value MUST be greater than zero.
If set, all transfers SHALL pay at least this amount. | +| maximum_amount | [int64](#int64) | | A maximum fee to charge, in units of 10-decimals tokens.

This value is OPTIONAL, with a default of `0` indicating no maximum.
If set, this value MUST be greater than zero.
If set, any fee charged SHALL NOT exceed this value.
This value SHOULD be strictly greater than `minimum_amount`. If this amount is less than or equal to `minimum_amount`, then the fee charged SHALL always be equal to this value and `fractional_amount` SHALL NOT have any effect. | +| net_of_transfers | [bool](#bool) | | Flag requesting to assess the calculated fee against the sender, without reducing the amount transferred.

Effects of this flag

  1. If this value is true
    • The receiver of a transfer SHALL receive the entire amount sent.
    • The fee SHALL be charged to the sender as an additional amount, increasing the token transfer debit.
  2. If this value is false
    • The receiver of a transfer SHALL receive the amount sent _after_ deduction of the calculated fee.
| + + + + + + + + +### RoyaltyFee +A fee to assess during a CryptoTransfer that changes ownership of a +non-fungible/unique (NFT) token.
+This message defines the fraction of the fungible value exchanged for an +NFT that the ledger should collect as a royalty. +"Fungible value" includes both HBAR (ℏ) and units of fungible HTS tokens. +When the NFT sender does not receive any fungible value, the ledger will +assess the fallback fee, if present, to the new NFT owner. Royalty fees +can only be added to non-fungible/unique tokens. + +#### Important Note +> Users should be aware that native royalty fees are _strictly_ a +> convenience feature, SHALL NOT be guaranteed, and the network SHALL NOT +> enforce _inescapable_ royalties on the exchange of a unique NFT.
+> For _one_ example, if the counterparties agree to split their value +> transfer and NFT exchange into separate transactions, the network cannot +> possibly determine the value exchanged. Even trustless transactions, +> using a smart contract or other form of escrow, can arrange such split +> transactions as a single _logical_ transfer. + +Counterparties that wish to _respect_ creator royalties MUST follow the +pattern the network recognizes. +
+A single transaction MUST contain all three elements, transfer of the NFT, +debit of fungible value from the receiver, and credit of fungible value to +the sender, in order for the network to accurately assess royalty fees. +
+
+Two examples are presented here. +
+The NFT sender and receiver MUST both sign a single `cryptoTransfer` that +transfers the NFT from sender to receiver, debits the fungible value from +the receiver, and credits the sender with the fungible value the receiver +is exchanging for the NFT.
+A marketplace using an approved spender account for an escrow transaction +MUST credit the account selling the NFT in the same `cryptoTransfer` +transaction that transfers the NFT to, and deducts fungible value from, +the buying account. +
+This type of fee MAY NOT produce accurate results if multiple transfers +are executed in a single transaction. It is RECOMMENDED that each +NFT subject to royalty fees be transferred separately and without +unrelated fungible token transfers. + +The network SHALL NOT consider third-party transfers, including +"approved spender" accounts, in collecting royalty fees. An honest +broker MUST ensure that transfer of an NFT and payment delivered to +the sender are present in the same transaction. +There is an +[open suggestion](https://github.com/hashgraph/hedera-improvement-proposal/discussions/578) +that proposes to broaden the scope of transfers from which the network +automatically collects royalties to cover related third parties. If this +interests or concerns you, please add your voice to that discussion. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| exchange_value_fraction | [Fraction](#proto-Fraction) | | The fraction of fungible value exchanged for an NFT to collect as royalty.

This SHALL be applied once to the total fungible value transferred for the transaction.
There SHALL NOT be any adjustment based on multiple transfers involving the NFT sender as part of a single transaction. | +| fallback_fee | [FixedFee](#proto-FixedFee) | | A fixed fee to assess if no fungible value is known to be traded for the NFT.

If an NFT is transferred without a corresponding transfer of _fungible_ value returned in the same transaction, the network SHALL charge this fee as a fallback.
Fallback fees MAY have unexpected effects when interacting with escrow, market transfers, and smart contracts. It is RECOMMENDED that developers carefully consider possible effects from fallback fees when designing systems that facilitate the transfer of NFTs. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/duration.md b/documents/api/services/duration.md new file mode 100644 index 00000000..9e27a711 --- /dev/null +++ b/documents/api/services/duration.md @@ -0,0 +1,50 @@ +## Table of Contents + +- [duration.proto](#duration-proto) + - [Duration](#proto-Duration) + + + + + +

Top

+ +## duration.proto +# Duration +A duration, in seconds. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### Duration +A length of time in seconds. + +It is RECOMMENDED that this message be used whenever an amount of time, +rather than a specific point in time, is needed. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| seconds | [int64](#int64) | | The number of seconds for this duration. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/ethereum_transaction.md b/documents/api/services/ethereum_transaction.md new file mode 100644 index 00000000..cc98126d --- /dev/null +++ b/documents/api/services/ethereum_transaction.md @@ -0,0 +1,61 @@ +## Table of Contents + +- [ethereum_transaction.proto](#ethereum_transaction-proto) + - [EthereumTransactionBody](#proto-EthereumTransactionBody) + + + + + +

Top

+ +## ethereum_transaction.proto +# Ethereum Call +Make an Ethereum transaction "call" with all data in Ethereum formats, +including the contract alias. Call data may be in the transaction, +or stored within an Hedera File.
+The caller MAY offer additional gas above what is offered in the call +data, but MAY be charged up to 80% of that value if the amount required +is less than this "floor" amount. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### EthereumTransactionBody +A transaction in Ethereum format.
+Make an Ethereum transaction "call" with all data in Ethereum formats, +including the contract alias. Call data may be in the transaction, or +stored within an Hedera File. + +The caller MAY offer additional gas above what is offered in the call data, +but MAY be charged up to 80% of that value if the amount required is less +than this "floor" amount. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| ethereum_data | [bytes](#bytes) | | The raw Ethereum transaction data.

This transaction MUST be RLP encoded.
This SHALL be the complete transaction data unless the `call_data` field is set.
If `call_data` is set, this field SHALL be modified to replace the `callData` element with the content of the referenced file.
The transaction signature SHALL be validated after `callData` is complete, if necessary. | +| call_data | [FileID](#proto-FileID) | | The `callData` for the Ethereum transaction.

If this field is set, the data in the `ethereum_data` field SHALL be re-written to replace the `callData` element with the contents of this file at time of execution.
The Ethereum transaction MUST be "rehydrated" with this modified `callData` before signature validation MAY be performed. | +| max_gas_allowance | [int64](#int64) | | A maximum amount of "gas" offered to pay the Ethereum transaction costs.

This gas offered is in addition to any gas supplied with the Ethereum transaction as declared in the `ethereum_data`.
In most circumstances the account with an alias matching the public key available from the Ethereum transaction signature offers sufficient gas to power the transaction, but in some cases it MAY be desirable for the account submitting this transaction to either supplement or entirely fund the transaction cost.
The amount of gas offered here SHALL be used to pay for transaction costs _in excess_ of any gas offered within the Ethereum transaction.
If the gas offered within the Ethereum transaction is sufficient for all costs, the gas offered in this field SHALL NOT be expended.
Regardless of actual transaction cost, the payer for this transaction SHALL NOT be charged more gas than the amount offered here.
If the sum of both gas amounts is not sufficient to pay for the transaction, the entire total amount of gas offered SHALL be expended, the transaction SHALL fail, and the response code `INSUFFICIENT_GAS` SHALL be set.
If any amount of gas is charged to the payer of this transaction, at least 80% of the value offered in this field SHALL be charged as a minimum fee.
If the amount of gas authorized in the Ethereum transaction data is `0`, then the payer of this transaction SHALL be charged the entire cost of the Ethereum transaction, subject to the limit set in this field. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/exchange_rate.md b/documents/api/services/exchange_rate.md new file mode 100644 index 00000000..8b625fe6 --- /dev/null +++ b/documents/api/services/exchange_rate.md @@ -0,0 +1,93 @@ +## Table of Contents + +- [exchange_rate.proto](#exchange_rate-proto) + - [ExchangeRate](#proto-ExchangeRate) + - [ExchangeRateSet](#proto-ExchangeRateSet) + + + + + +

Top

+ +## exchange_rate.proto +# Exchange Rates +Exchange rates that define ratios between HBAR and USD. + +Fees are denominated in USD, but paid in HBAR, so accurate exchange +rates are important and the exchange rates kept in state are updated +frequently.
+Exchange rates are also reported in every receipt for fee transparency. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ExchangeRate +An exchange rate as a ratio of USD cents per HBAR. + +This ratio SHALL be used to convert tinycent (`10-8` USD cent) +to tinybar for fees and other purposes.
+When applying an `ExchangeRate`, implementations SHOULD ensure input values +are `tinycent` and/or `tinybar` before applying the exchange ratio.
+Exchange results MAY be converted to USD or HBAR via division if whole +unit values are required. + +The ratio described here SHALL be assigned such that a value in `tinybar` +may be obtained with the following equation. +``` + amountInTinybar = (amountInTinycent * hbarEquiv) / centEquiv +``` + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| hbarEquiv | [int32](#int32) | | Denominator for a ratio of USD cents per HBAR. | +| centEquiv | [int32](#int32) | | Numerator for a ratio of USD cents per HBAR. | +| expirationTime | [TimestampSeconds](#proto-TimestampSeconds) | | Expiration time stamp for this exchange rate. | + + + + + + + + +### ExchangeRateSet +A set of two exchange rates.
+The exchange rate for the network is stored and reported as a set of +two rates; current and next. This structure supports the network cleanly +switching between exchange rates when necessary. This also provides clear +notice to clients when the exchange rate will change and the exchange +rate that will be applied for the next time period. + +The difference in rate between `currentRate` and `nextRate` MUST NOT exceed +the configured maximum percentage change. This limit SHALL be a +network configuration value. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| currentRate | [ExchangeRate](#proto-ExchangeRate) | | A current exchange rate.

When present in a receipt, this SHALL be the exchange rate used to compute the fees for that transaction. | +| nextRate | [ExchangeRate](#proto-ExchangeRate) | | A future exchange rate.

This exchange rate SHALL be applied after the current exchange rate expires. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/file_append.md b/documents/api/services/file_append.md new file mode 100644 index 00000000..1a394ec6 --- /dev/null +++ b/documents/api/services/file_append.md @@ -0,0 +1,69 @@ +## Table of Contents + +- [file_append.proto](#file_append-proto) + - [FileAppendTransactionBody](#proto-FileAppendTransactionBody) + + + + + +

Top

+ +## file_append.proto +# File Append +A transaction body message to append data to a "file" in state. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### FileAppendTransactionBody +A transaction body for an `appendContent` transaction.
+This transaction body provides a mechanism to append content to a "file" in +network state. Hedera transactions are limited in size, but there are many +uses for in-state byte arrays (e.g. smart contract bytecode) which require +more than may fit within a single transaction. The `appendFile` transaction +exists to support these requirements. The typical pattern is to create a +file, append more data until the full content is stored, verify the file is +correct, then update the file entry with any final metadata changes (e.g. +adding threshold keys and removing the initial upload key). + +Each append transaction MUST remain within the total transaction size limit +for the network (typically 6144 bytes).
+The total size of a file MUST remain within the maximum file size limit for +the network (typically 1048576 bytes). + +Append transactions MUST have signatures from _all_ keys in the `KeyList` +assigned to the `keys` field of the file.
+See the [File Service](#FileService) specification for a detailed +explanation of the signature requirements for all file transactions. + +### Record Stream Effects +???? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| fileID | [FileID](#proto-FileID) | | A file identifier.
This identifies the file to which the `contents` will be appended.

This field is REQUIRED.
The identified file MUST exist.
The identified file MUST NOT be larger than the current maximum file size limit.
The identified file MUST NOT be deleted.
The identified file MUST NOT be immutable. | +| contents | [bytes](#bytes) | | An array of bytes to append.

This content SHALL be appended to the identified file if this transaction succeeds.
This field is REQUIRED.
This field MUST NOT be empty. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/file_create.md b/documents/api/services/file_create.md new file mode 100644 index 00000000..687024b0 --- /dev/null +++ b/documents/api/services/file_create.md @@ -0,0 +1,91 @@ +## Table of Contents + +- [file_create.proto](#file_create-proto) + - [FileCreateTransactionBody](#proto-FileCreateTransactionBody) + + + + + +

Top

+ +## file_create.proto +# File Create +Messages to create a new file entry. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### FileCreateTransactionBody +Create a new file. + +If successful, the new file SHALL contain the (possibly empty) content +provided in the `contents` field.
+When the current consensus time exceeds the `expirationTime` value, the +network SHALL expire the file, and MAY archive the state entry. + +#### Signature Requirements +The HFS manages file authorization in a manner that can be confusing. +The core element of file authorization is the `keys` field, +which is a `KeyList`; a list of individual `Key` messages, each of which +may represent a simple or complex key.
+The file service transactions treat this list differently.
+A `fileCreate`, `fileAppend`, or `fileUpdate` MUST have a valid signature +from _each_ key in the list.
+A `fileDelete` MUST have a valid signature from _at least one_ key in +the list. This is different, and allows a file "owned" by many entities +to be deleted by any one of those entities. A deleted file cannot be +restored, so it is important to consider this when assigning keys for +a file.
+If any of the keys in a `KeyList` are complex, the full requirements of +each complex key must be met to count as a "valid signature" for that key. +A complex key structure (i.e. a `ThresholdKey`, or `KeyList`, possibly +including additional `ThresholdKey` or `KeyList` descendants) may be +assigned as the sole entry in a file `keys` field to ensure all transactions +have the same signature requirements. + +If the `keys` field is an empty `KeyList`, then the file SHALL be immutable +and the only transaction permitted to modify that file SHALL be a +`fileUpdate` transaction with _only_ the `expirationTime` set. + +#### Shard and Realm +The current API ignores shardID and realmID. All files are created in +shard 0 and realm 0. Future versions of the API may support multiple +realms and multiple shards. + +### Record Stream Effects +After the file is created, the FileID for it SHALL be returned in the +transaction receipt, and SHALL be recorded in the transaction record. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| expirationTime | [Timestamp](#proto-Timestamp) | | An expiration timestamp.

When the network consensus time exceeds this value, the network SHALL expire the file. | +| keys | [KeyList](#proto-KeyList) | | A list of keys that represent file "owners".

Every `Key` in this list MUST sign this `fileCreate` transaction, as well as any `fileUpdate` or `fileAppend` that modifies this file.
At least one `Key` in this list MUST sign any `fileDelete` transaction to delete this file.
If this `KeyList` is empty, the file SHALL be created immutable and the only field that may be changed subsequently is the `expirationTime`. An immutable file cannot be deleted except with a `systemDelete` transaction, or by expiration. | +| contents | [bytes](#bytes) | | A byte array of file content.

The file SHALL be created with initial content equal to this field.
Additional `fileAppend` transactions MAY add additional content to the end of this file.
A `fileUpdate` transaction MAY replace the file content. | +| shardID | [ShardID](#proto-ShardID) | | A shard in which this file is created | +| realmID | [RealmID](#proto-RealmID) | | A realm in which this file is created.

The shard number for this realm MUST match the value in `shardID`.
Currently, this MUST be `0` for both fields.
If the desired realm is `0.0`, this SHOULD NOT be set. | +| newRealmAdminKey | [Key](#proto-Key) | | **Deprecated.** An admin key for a new realm, if one is created.

Should this be deprecated?
The "create realm" was never enabled, and probably should not be possible on file creation.
Added deprecated tag 2024-05 based on above. | +| memo | [string](#string) | | A short description of this file.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/file_delete.md b/documents/api/services/file_delete.md new file mode 100644 index 00000000..72c97ff5 --- /dev/null +++ b/documents/api/services/file_delete.md @@ -0,0 +1,58 @@ +## Table of Contents + +- [file_delete.proto](#file_delete-proto) + - [FileDeleteTransactionBody](#proto-FileDeleteTransactionBody) + + + + + +

Top

+ +## file_delete.proto +# File Delete +A message for a transaction to delete a file. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### FileDeleteTransactionBody +Mark a file as deleted and remove its content from network state. + +At least _one_ key from the `KeyList` in the `keys` field of the +identified file MUST sign this transaction.
+The metadata for a deleted file SHALL be retained at least until the +expiration time for the file is exceeded.
+On completion, the identified file SHALL be marked `deleted`.
+On completion, the identified file SHALL have an empty `contents` array.
+This transaction SHALL be final and irreversible. + +### Record Stream Effects +???? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| fileID | [FileID](#proto-FileID) | | A file identifier.
This identifies the file to delete.

This field is REQUIRED. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/file_get_contents.md b/documents/api/services/file_get_contents.md new file mode 100644 index 00000000..ef57cb88 --- /dev/null +++ b/documents/api/services/file_get_contents.md @@ -0,0 +1,87 @@ +## Table of Contents + +- [file_get_contents.proto](#file_get_contents-proto) + - [FileGetContentsQuery](#proto-FileGetContentsQuery) + - [FileGetContentsResponse](#proto-FileGetContentsResponse) + - [FileGetContentsResponse.FileContents](#proto-FileGetContentsResponse-FileContents) + + + + + +

Top

+ +## file_get_contents.proto +# File Get Contents +Messages for a query to retrieve the content of a file in the +Hedera File Service (HFS). + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### FileGetContentsQuery +A query request to the Hedera File Service (HFS) for file content. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.
This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither). | +| fileID | [FileID](#proto-FileID) | | A file identifier.

This MUST be the identifier of a file that exists in HFS.
This value SHALL identify the file to be queried. | + + + + + + + + +### FileGetContentsResponse +A response to a query for the content of a file in the +Hedera File Service (HFS). + +This message SHALL contain the full content of the requested file, but +SHALL NOT contain any metadata. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| fileContents | [FileGetContentsResponse.FileContents](#proto-FileGetContentsResponse-FileContents) | | A combination of File identifier and content bytes.

This SHALL NOT be set if the file does not exist.
The network MAY generate a state proof for this field. | + + + + + + + + +### FileGetContentsResponse.FileContents + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| fileID | [FileID](#proto-FileID) | | A file identifier.

This SHALL be the identifier of a file that exists in HFS.
This value SHALL identify the file that was queried. | +| contents | [bytes](#bytes) | | A byte array of file content.

This SHALL contain the full content of the requested file.
This SHALL be empty if, and only if, the file content is empty. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/file_get_info.md b/documents/api/services/file_get_info.md new file mode 100644 index 00000000..ec68eaa9 --- /dev/null +++ b/documents/api/services/file_get_info.md @@ -0,0 +1,98 @@ +## Table of Contents + +- [file_get_info.proto](#file_get_info-proto) + - [FileGetInfoQuery](#proto-FileGetInfoQuery) + - [FileGetInfoResponse](#proto-FileGetInfoResponse) + - [FileGetInfoResponse.FileInfo](#proto-FileGetInfoResponse-FileInfo) + + + + + +

Top

+ +## file_get_info.proto +# File Get Information +Messages for a query to retrieve the metadata for a file in the +Hedera File Service (HFS). + +The query defined here does not include the content of the file. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### FileGetInfoQuery +Query to request file metadata from the Hedera File Service (HFS).
+This query requests all of the information _about_ a file, but none of the +_content_ of a file. A client should submit a `fileGetContents` query to +view the content of a file. File content _may_ also be available from a +block node or mirror node, generally at lower cost. + +File metadata SHALL be available for active files and deleted files.
+File metadata MAY be unavailable for expired files.
+The size of a deleted file SHALL be `0` and the content SHALL be empty. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.
This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither). | +| fileID | [FileID](#proto-FileID) | | A file identifier.

This MUST be the identifier of a file that exists in HFS.
This value SHALL identify the file to be queried. | + + + + + + + + +### FileGetInfoResponse +A response to a query for the metadata of a file in the HFS. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| fileInfo | [FileGetInfoResponse.FileInfo](#proto-FileGetInfoResponse-FileInfo) | | A combination of fields from the requested file metadata.

This SHALL NOT be set if the identified file does not exist or has expired. | + + + + + + + + +### FileGetInfoResponse.FileInfo + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| fileID | [FileID](#proto-FileID) | | A file identifier.

This SHALL be the identifier of a file that exists in HFS.
This value SHALL identify the file that was queried. | +| size | [int64](#int64) | | A size, in bytes, for the file. | +| expirationTime | [Timestamp](#proto-Timestamp) | | An expiration timestamp.

The file SHALL NOT expire before the network consensus time exceeds this value.
The file SHALL expire after the network consensus time exceeds this value.
| +| deleted | [bool](#bool) | | A flag indicating this file is deleted.

A deleted file SHALL have a size `0` and empty content. | +| keys | [KeyList](#proto-KeyList) | | A KeyList listing all keys that "own" the file.

All keys in this list MUST sign a transaction to append to the file content, or to modify file metadata.
At least _one_ key in this list MUST sign a transaction to delete this file.
If this is an empty `KeyList`, the file is immutable, cannot be modified or deleted, but MAY expire. A `fileUpdate` transaction MAY extend the expiration time for an immutable file. | +| memo | [string](#string) | | A short description for this file.

This value, if set, SHALL NOT exceed 100 bytes when encoded as UTF-8. | +| ledger_id | [bytes](#bytes) | | A ledger identifier for the responding network.

This value SHALL identify the distributed ledger that responded to this query. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/file_service.md b/documents/api/services/file_service.md new file mode 100644 index 00000000..a7805c5f --- /dev/null +++ b/documents/api/services/file_service.md @@ -0,0 +1,74 @@ +## Table of Contents + +- [file_service.proto](#file_service-proto) + - [FileService](#proto-FileService) + + + + + +

Top

+ +## file_service.proto +# File Service +gRPC definitions for the Hedera File Service (HFS). + +The HFS manages bulk data in the form of byte arrays of arbitrary +size, up to a network-configured maximum size. These files are +most often used to store bulk data for distributed applications +and smart contracts. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + + + + + + + +### FileService +Service gRPC definitions for the Hedera File Service (HFS). + +#### Signature Requirements +The HFS manages file authorization in a manner that can confuse a new +developer. The core element of file authorization is the `keys` field, +which is a `KeyList`; a list of individual `Key` messages, each of which +may represent a simple or complex key.
+The file service transactions treat this list differently.
+A `fileCreate`, `fileAppend`, or `fileUpdate` MUST have a valid signature +from _each_ key in the list.
+A `fileDelete` MUST have a valid signature from _at least one_ key in +the list. This is different, and allows a file "owned" by many entities +to be deleted by any one of those entities. A deleted file cannot be +restored, so it is important to consider this when assigning keys for +a file.
+If any of the keys in a `KeyList` are complex, the full requirements of +each complex key must be met to count as a "valid signature" for that key. +A complex key structure (i.e. a `ThresholdKey`, or `KeyList`, possibly +including additional `ThresholdKey` or `KeyList` descendants) may be +assigned as the sole entry in a file `keys` field to ensure all transactions +have the same signature requirements. + +| Method Name | Request Type | Response Type | Description | +| ----------- | ------------ | ------------- | ------------| +| createFile | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Create a file in HFS. | +| updateFile | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Update a file in HFS. | +| deleteFile | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Delete a file in HFS.
The content of a file deleted in this manner is completely removed from network state. | +| appendContent | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Append to a file in HFS. | +| getFileContent | [Query](#proto-Query) | [Response](#proto-Response) | Retrieve the content of a file in HFS.
Note that this query retrieves _only_ the file content, not any of the metadata for the file. | +| getFileInfo | [Query](#proto-Query) | [Response](#proto-Response) | Retrieve the metadata for a file in HFS.
Note that this query does not retrieve the file _content_. | +| systemDelete | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Delete a "regular" file without "owner" authorization.
This transaction _does not_ require signatures for the keys in the file `keys` list, but must be signed by a "privileged" account.

This transaction SHALL NOT accept a file identifier for a "system" file.
This transaction SHALL NOT remove the _content_ of the file from state. This permits use of the `systemUndelete` to reverse this action if performed in error.

This is a privileged transaction, and only accounts 2-59 are permitted to call this function, by default. The actual restriction is in the `api-permission.properties` file in the consensus node configuration. | +| systemUndelete | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Undelete a "regular" file. This transaction must be signed by a "privileged" account.

This transaction SHALL NOT accept a file identifier for a "system" file.
The file identified MUST be deleted.
This transaction SHALL NOT recover the _content_ of a file unless that file was deleted with a `systemDelete` transaction. The _content_ of a file deleted with a `fileDelete` transaction is not retained in state.

This is a privileged transaction, and only accounts 2-60 are permitted to call this function, by default. The actual restriction is in the `api-permission.properties` file in the consensus node configuration. | + + + + + diff --git a/documents/api/services/file_update.md b/documents/api/services/file_update.md new file mode 100644 index 00000000..ad9517ba --- /dev/null +++ b/documents/api/services/file_update.md @@ -0,0 +1,62 @@ +## Table of Contents + +- [file_update.proto](#file_update-proto) + - [FileUpdateTransactionBody](#proto-FileUpdateTransactionBody) + + + + + +

Top

+ +## file_update.proto +# File Update +A message to modify the metadata for a file and/or _replace_ the contents. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### FileUpdateTransactionBody +Update the metadata, and/or replace the content, of a file in the +Hedera File Service (HFS). + +Any field, other than `fileID` which is not set (i.e. is null) +in this message SHALL be ignored.
+Every `Key` in the `keys` list for the identified file MUST sign this +transaction.
+If the `keys` list for the identified file is an empty `KeyList`, then +this message MUST NOT set any field except `expirationTime`. + +### Record Stream Effects +???? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| fileID | [FileID](#proto-FileID) | | A file identifier for the file to update.

This field is REQUIRED. | +| expirationTime | [Timestamp](#proto-Timestamp) | | An expiration timestamp.

If set, this value MUST be strictly later than the existing `expirationTime` value.
If set, this value SHALL replace the existing `expirationTime`.
If this field is the only field set, then this transaction SHALL NOT require any signature other than the `payer` for the transaction.
When the network consensus time exceeds the then-current `expirationTime`, the network SHALL expire the file. | +| keys | [KeyList](#proto-KeyList) | | The new list of keys that "own" this file.

If set, every key in this `KeyList` MUST sign this transaction.
If set, every key in the _previous_ `KeyList` MUST _also_ sign this transaction.
If this value is an empty `KeyList`, then the file SHALL be immutable after completion of this transaction. | +| contents | [bytes](#bytes) | | An array of bytes.

This value, if set, SHALL _replace_ the existing file content. If this value is set to an empty byte array, the content of the file SHALL be unchanged.

REVIEW NOTE
This is a CHANGE from current behavior, but is REQUIRED because the "default" value for a PBJ `Bytes` is no longer `null`, but is `Bytes.EMPTY`. We may have to make a change here to enable clearing the content of a file post-modularization...
| +| memo | [google.protobuf.StringValue](#google-protobuf-StringValue) | | A short description of this file.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/freeze.md b/documents/api/services/freeze.md new file mode 100644 index 00000000..f8cfa6f7 --- /dev/null +++ b/documents/api/services/freeze.md @@ -0,0 +1,77 @@ +## Table of Contents + +- [freeze.proto](#freeze-proto) + - [FreezeTransactionBody](#proto-FreezeTransactionBody) + + + + + +

Top

+ +## freeze.proto +# Freeze +Transaction body for a network "freeze" transaction. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### FreezeTransactionBody +A transaction body for all five freeze transactions. + +Combining five different transactions into a single message, this +transaction body MUST support options to schedule a freeze, abort a +scheduled freeze, prepare a software upgrade, prepare a telemetry +upgrade, or initiate a software upgrade. + +For a scheduled freeze, at the scheduled time, according to +network consensus time + - A freeze causes the network nodes to stop creating events or accepting + transactions, and enter a persistent maintenance state. + - A freeze upgrade causes the network nodes to stop creating events or + accepting transactions, and upgrade the node software from a previously + prepared upgrade package. The network nodes then restart and rejoin + the network after upgrading. + +For other freeze types, immediately upon processing the freeze transaction + - A Freeze Abort cancels any pending scheduled freeze. + - A prepare upgrade begins to extract the contents of the specified + upgrade file to the local filesystem. + - A telemetry upgrade causes the network nodes to extract a telemetry + upgrade package to the local filesystem and signal other software + on the machine to upgrade, without impacting the node or + network processing. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| startHour | [int32](#int32) | | **Deprecated.** Rejected if set; replace with `start_time`.
The start hour (in UTC time), a value between 0 and 23 | +| startMin | [int32](#int32) | | **Deprecated.** Rejected if set; replace with `start_time`.
The start minute (in UTC time), a value between 0 and 59 | +| endHour | [int32](#int32) | | **Deprecated.** Rejected if set; end time is neither assigned nor guaranteed and depends on many uncontrolled factors.
The end hour (in UTC time), a value between 0 and 23 | +| endMin | [int32](#int32) | | **Deprecated.** Rejected if set; end time is neither assigned nor guaranteed and depends on many uncontrolled factors.
The end minute (in UTC time), a value between 0 and 59 | +| update_file | [FileID](#proto-FileID) | | An upgrade file.

If set, the identifier of a file in network state.
The contents of this file MUST be a `zip` file and this data SHALL be extracted to the node filesystem during a `PREPARE_UPGRADE` freeze type.
The `file_hash` field MUST match the SHA384 hash of the content of this file.
The extracted data SHALL be used to perform a network software update if a `FREEZE_UPGRADE` freeze type is subsequently processed. | +| file_hash | [bytes](#bytes) | | A SHA384 hash of file content.
This is a hash of the file identified by `update_file`.

This MUST be set if `update_file` is set, and MUST match the SHA384 hash of the contents of that file. | +| start_time | [Timestamp](#proto-Timestamp) | | A start time for the freeze.

If this field is REQUIRED for the specified `freeze_type`, then when the network consensus time reaches this instant

  1. The network SHALL stop accepting transactions.
  2. The network SHALL gossip a freeze state.
  3. The nodes SHALL, in coordinated order, disconnect and shut down.
  4. The nodes SHALL halt or perform a software upgrade, depending on `freeze_type`.
  5. If the `freeze_type` is `FREEZE_UPGRADE`, the nodes SHALL restart and rejoin the network upon completion of the software upgrade.
If the `freeze_type` is `TELEMETRY_UPGRADE`, the start time is required, but the network SHALL NOT stop, halt, or interrupt transaction processing. The required field is an historical anomaly and SHOULD change in a future release.
| +| freeze_type | [FreezeType](#proto-FreezeType) | | The type of freeze.

This REQUIRED field effectively selects between five quite different transactions in the same transaction body. Depending on this value the service may schedule a freeze, prepare upgrades, perform upgrades, or even abort a previously scheduled freeze. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/freeze_service.md b/documents/api/services/freeze_service.md new file mode 100644 index 00000000..36e6c7c5 --- /dev/null +++ b/documents/api/services/freeze_service.md @@ -0,0 +1,45 @@ +## Table of Contents + +- [freeze_service.proto](#freeze_service-proto) + - [FreezeService](#proto-FreezeService) + + + + + +

Top

+ +## freeze_service.proto +# Freeze Service +A service to manage network freeze events. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + + + + + + + +### FreezeService +A service to manage network "freeze" events. + +This service provides a facility to prepare for network upgrades, halt network processing, +perform network software upgrades, and automatically restart the network following an upgrade. + +| Method Name | Request Type | Response Type | Description | +| ----------- | ------------ | ------------- | ------------| +| freeze | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Freeze, cancel, or prepare a freeze. This single transaction performs all of the functions supported by the network freeze service. These functions include actions to prepare an upgrade, prepare a telemetry upgrade, freeze the network, freeze the network for upgrade, or abort a scheduled freeze.

The actual freeze action SHALL be determined by the `freeze_type` field of the `FreezeTransactionBody`.
The transaction body MUST be a `FreezeTransactionBody`. | + + + + + diff --git a/documents/api/services/freeze_type.md b/documents/api/services/freeze_type.md new file mode 100644 index 00000000..04023578 --- /dev/null +++ b/documents/api/services/freeze_type.md @@ -0,0 +1,52 @@ +## Table of Contents + +- [freeze_type.proto](#freeze_type-proto) + - [FreezeType](#proto-FreezeType) + + + + + +

Top

+ +## freeze_type.proto +# Freeze Type +An enumeration to select the type of a network freeze. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + + + +### FreezeType +An enumeration of possible network freeze types. + +Each enumerated value SHALL be associated to a single network freeze +scenario. Each freeze scenario defines the specific parameters +REQUIRED for that freeze. + +| Name | Number | Description | +| ---- | ------ | ----------- | +| UNKNOWN_FREEZE_TYPE | 0 | An invalid freeze type.

The first value in a protobuf enum is a default value. This default is RECOMMENDED to be an invalid value to aid in detecting unset fields. | +| FREEZE_ONLY | 1 | Freeze the network, and take no further action.

The `start_time` field is REQUIRED and SHOULD be between `300` and `3600` seconds after the transaction identifier `transactionValidStart` field.
The fields `update_file` and `file_hash` SHALL be ignored.
A `FREEZE_ONLY` transaction SHALL NOT perform any network changes or upgrades.
After this freeze is processed manual intervention is REQUIRED to restart the network. | +| PREPARE_UPGRADE | 2 | This freeze type does not freeze the network, but begins "preparation" to upgrade the network.

The fields `update_file` and `file_hash` are REQUIRED and MUST be valid.
The `start_time` field SHALL be ignored.
A `PREPARE_UPGRADE` transaction SHALL NOT freeze the network or interfere with general transaction processing.
If this freeze type is initiated after a `TELEMETRY_UPGRADE`, the prepared telemetry upgrade SHALL be reset and all telemetry upgrade artifacts in the filesystem SHALL be deleted.
At some point after this freeze type completes (dependent on the size of the upgrade file), the network SHALL be prepared to complete a software upgrade of all nodes. | +| FREEZE_UPGRADE | 3 | Freeze the network to perform a software upgrade.

The `start_time` field is REQUIRED and SHOULD be between `300` and `3600` seconds after the transaction identifier `transactionValidStart` field.
A software upgrade file MUST be prepared prior to this transaction.
After this transaction completes, the network SHALL initiate an upgrade and restart of all nodes at the start time specified. | +| FREEZE_ABORT | 4 | Abort a pending network freeze operation.

All fields SHALL be ignored for this freeze type.
This freeze type MAY be submitted after a `FREEZE_ONLY`, `FREEZE_UPGRADE`, or `TELEMETRY_UPGRADE` is initiated.
This freeze type MUST be submitted and reach consensus before the `start_time` designated for the current pending freeze to be effective.
After this freeze type is processed, the upgrade file hash and pending freeze start time stored in the network SHALL be reset to default (empty) values. | +| TELEMETRY_UPGRADE | 5 | Prepare an upgrade of auxiliary services and containers providing telemetry/metrics.

The `start_time` field is REQUIRED and SHOULD be between `300` and `3600` seconds after the transaction identifier `transactionValidStart` field.
The `update_file` field is REQUIRED and MUST be valid.
A `TELEMETRY_UPGRADE` transaction SHALL NOT freeze the network or interfere with general transaction processing.
This freeze type MUST NOT be initiated between a `PREPARE_UPGRADE` and `FREEZE_UPGRADE`. If this freeze type is initiated after a `PREPARE_UPGRADE`, the prepared upgrade SHALL be reset and all software upgrade artifacts in the filesystem SHALL be deleted.
At some point after this freeze type completes (dependent on the size of the upgrade file), the network SHALL automatically upgrade the telemetry/metrics services and containers as directed in the specified telemetry upgrade file.

The condition that `start_time` is REQUIRED is an historical anomaly and SHOULD change in a future release.
| + + + + + + + + + + diff --git a/documents/api/services/get_account_details.md b/documents/api/services/get_account_details.md new file mode 100644 index 00000000..812aeac7 --- /dev/null +++ b/documents/api/services/get_account_details.md @@ -0,0 +1,227 @@ +## Table of Contents + +- [get_account_details.proto](#get_account_details-proto) + - [GetAccountDetailsQuery](#proto-GetAccountDetailsQuery) + - [GetAccountDetailsResponse](#proto-GetAccountDetailsResponse) + - [GetAccountDetailsResponse.AccountDetails](#proto-GetAccountDetailsResponse-AccountDetails) + - [GrantedCryptoAllowance](#proto-GrantedCryptoAllowance) + - [GrantedNftAllowance](#proto-GrantedNftAllowance) + - [GrantedTokenAllowance](#proto-GrantedTokenAllowance) + + + + + +

Top

+ +## get_account_details.proto +# Get Account Details +A standard query to inspect the full detail of an account. + +> REVIEW NOTE +>> This query in NetworkAdmin service duplicates CryptoGetInfo in Token Service.
+>> What is the value of having both?
+>> Should this version be deprecated? Should that version be deprecated? + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### GetAccountDetailsQuery +Request detail information about an account. + +The returned information SHALL include balance and allowances.
+The returned information SHALL NOT include a list of account records. + +#### Important +This query is a _privileged_ query. Only "system" accounts SHALL be +permitted to submit this query. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.
This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither). | +| account_id | [AccountID](#proto-AccountID) | | An account ID for which information is requested | + + + + + + + + +### GetAccountDetailsResponse +A response to a `GetAccountDetailsQuery`. + +This SHALL contain the account details if requested and successful. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| account_details | [GetAccountDetailsResponse.AccountDetails](#proto-GetAccountDetailsResponse-AccountDetails) | | Details of the account.

A state proof MAY be generated for this field. | + + + + + + + + +### GetAccountDetailsResponse.AccountDetails +Information describing A single Account in the Hedera distributed ledger. + +#### Attributes +Each Account may have a unique three-part identifier, a Key, and one or +more token balances. Accounts also have an alias, which has multiple +forms, and may be set automatically. Several additional items are +associated with the Account to enable full functionality. + +#### Expiration +Accounts, as most items in the network, have an expiration time, recorded +as a `Timestamp`, and must be "renewed" for a small fee at expiration. +This helps to reduce the amount of inactive accounts retained in state. +Another account may be designated to pay any renewal fees and +automatically renew the account for (by default) 30-90 days at a time as +a means to optionally ensure important accounts remain active. + +### Staking +Accounts may participate in securing the network by "staking" the account +balances to a particular network node, and receive a portion of network +fees as a reward. An account may optionally decline these rewards but +still stake its balances. + +#### Transfer Restrictions +An account may optionally require that inbound transfer transactions be +signed by that account as receiver (in addition to any other signatures +required, including sender). + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| account_id | [AccountID](#proto-AccountID) | | The unique ID of this account.

An account ID, when assigned to this field, SHALL be of the form `shard.realm.number`.
Transactions MAY reference the account by alias, but the account itself MUST always have a purely numeric identifier. This numeric ID is the value used to reference the account in query responses, transaction receipts, transaction records, and the block stream. | +| contract_account_id | [string](#string) | | A Solidity ID.

This SHALL be populated if this account is a smart contract, and SHALL NOT be populated otherwise.
This SHALL be formatted as a string according to Solidity ID standards. | +| deleted | [bool](#bool) | | A boolean indicating that this account is deleted. | +| proxy_account_id | [AccountID](#proto-AccountID) | | **Deprecated.** Replaced by StakingInfo.
ID of the account to which this account is staking its balances. If this account is not currently staking its balances, then this field, if set, SHALL be the sentinel value of `0.0.0`. | +| proxy_received | [int64](#int64) | | The total amount of tinybar proxy staked to this account. | +| key | [Key](#proto-Key) | | The key to be used to sign transactions from this account, if any.

This key SHALL NOT be set for hollow accounts until the account is finalized.
This key SHALL be set on all other accounts, except for certain immutable accounts (0.0.800 and 0.0.801) necessary for network function and otherwise secured by the governing council. | +| balance | [uint64](#uint64) | | The HBAR balance of this account, in tinybar (10-8 HBAR).

This value SHALL always be a whole number. | +| receiver_sig_required | [bool](#bool) | | A boolean indicating that the account requires a receiver signature for inbound token transfer transactions.

If this value is `true` then a transaction to transfer tokens to this account SHALL NOT succeed unless this account has signed the transfer transaction. | +| expiration_time | [Timestamp](#proto-Timestamp) | | The current expiration time for this account.

This account SHALL be due standard renewal fees when the network consensus time exceeds this time.
If rent and expiration are enabled for the network, and automatic renewal is enabled for this account, renewal fees SHALL be charged after this time, and, if charged, the expiration time SHALL be extended for another renewal period.
This account MAY be expired and removed from state at any point after this time if not renewed.
An account holder MAY extend this time by submitting an account update transaction to modify expiration time, subject to the current maximum expiration time for the network. | +| auto_renew_period | [Duration](#proto-Duration) | | A duration to extend this account's expiration.

The network SHALL extend the account's expiration by this duration, if funds are available, upon automatic renewal.
This SHALL NOT apply if the account is already deleted upon expiration.
If this is not provided in an allowed range on account creation, the transaction SHALL fail with INVALID_AUTO_RENEWAL_PERIOD. The default values for the minimum period and maximum period are currently 30 days and 90 days, respectively. | +| token_relationships | [TokenRelationship](#proto-TokenRelationship) | repeated | As of `HIP-367`, which enabled unlimited token associations, the potential scale for this value requires that users consult a mirror node for this information.
A list of tokens to which this account is "associated", enabling the transfer of that token type by this account.

REVIEW NOTE
Should this be deprecated, much as it is in crypto get info?
| +| memo | [string](#string) | | A short description of this account.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8. | +| owned_nfts | [int64](#int64) | | The total number of non-fungible/unique tokens owned by this account. | +| max_automatic_token_associations | [int32](#int32) | | The maximum number of tokens that can be auto-associated with the account.

If this is less than or equal to `used_auto_associations` (or 0), then this account MUST manually associate with a token before transacting in that token.
Following HIP-904 This value may also be `-1` to indicate no limit.
This value MUST NOT be less than `-1`. | +| alias | [bytes](#bytes) | | An account EVM alias.
This is a value used in some contexts to reference an account when the tripartite account identifier is not available.

This field, when set to a non-default value, is immutable and SHALL NOT be changed. | +| ledger_id | [bytes](#bytes) | | The ledger ID of the network that generated this response.
This is originally defined in `HIP-198` and depends on network configuration.
The current values, as of Q1 2024, are

Mainnet
0x00
Testnet
0x01
Previewnet
0x02
Undefined
0x03
Reserved
0x04
| +| granted_crypto_allowances | [GrantedCryptoAllowance](#proto-GrantedCryptoAllowance) | repeated | A list of crypto (HBAR) allowances approved by this account.

If this is not empty, each allowance SHALL permit a specified "spender" account to spend this account's HBAR balance, up to a designated limit.
This field SHALL permit spending only HBAR balance, not other tokens the account may hold.
Allowances for other tokens SHALL be listed in the `token_allowances` field or the `approve_for_all_nft_allowances` field. | +| granted_nft_allowances | [GrantedNftAllowance](#proto-GrantedNftAllowance) | repeated | A list of non-fungible token (NFT) allowances approved by this account.

If this is not empty, each allowance SHALL permit a specified "spender" account to transfer _all_ of this account's non-fungible/unique tokens from a particular collection.
Allowances for a specific serial number MUST be directly associated with that specific non-fungible/unique token, rather than the holding account. | +| granted_token_allowances | [GrantedTokenAllowance](#proto-GrantedTokenAllowance) | repeated | A list of fungible token allowances approved by this account.

If this is not empty, each allowance SHALL permit a specified "spender" to spend this account's fungible tokens, of the designated type, up to a designated limit. | + + + + + + + + +### GrantedCryptoAllowance +Permission granted by one account (the "funding" account) to another +account (the "spender" account) that allows the spender to spend a +specified amount of HBAR owned by the funding account. + +An allowance SHALL NOT transfer any HBAR directly, it only permits +transactions signed only by the spender account to transfer HBAR, up +to the amount specified, from the funding account. + +Once the specified amount is spent, the allowance SHALL be consumed +and a new allowance SHALL be required before that spending account +may spend additional HBAR from the funding account. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| spender | [AccountID](#proto-AccountID) | | The identifier for the spending account associated with this allowance.

This account SHALL be permitted to sign transactions to spend HBAR from the funding/allowing account.
This permission SHALL be limited to no more than the specified `amount`. | +| amount | [int64](#int64) | | The maximum amount that the spender account may transfer within the scope of this allowance.

This allowance SHALL be consumed if any combination of transfers authorized via this allowance meet this value in total.
This value MUST be specified in tinybar (i.e. 10-8 HBAR). | + + + + + + + + +### GrantedNftAllowance +Permission granted by one account (the "funding" account) to another +account (the "spender" account) that allows the spender to transfer +all serial numbers of a specific non-fungible/unique token (NFT) +collection owned by the funding account.
+This is a broad permission, as it does not matter how many NFTs of the +specified collection the funding account owns, the spender MAY dispose +of any or all of them with this allowance.
+Each token type (typically a collection of NFTs) SHALL require +a separate allowance.
+Allowances for a specific serial number MUST be directly associated +with that specific non-fungible/unique token, rather than +the holding account. + +An allowance SHALL NOT transfer any tokens directly, it only permits +transactions signed only by the spender account to transfer any +non-fungible/unique tokens of the specified type owned by +the funding account. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| token_id | [TokenID](#proto-TokenID) | | The identifier for the token associated with this allowance.

This token MUST be a non-fungible/unique token. | +| spender | [AccountID](#proto-AccountID) | | The identifier for the spending account associated with this allowance.

This account SHALL be permitted to sign transactions to spend tokens of the associated token type from the funding/allowing account. | + + + + + + + + +### GrantedTokenAllowance +Permission granted by one account (the "funding" account) to another +account (the "spender" account) that allows the spender to spend a +specified amount of a specific non-HBAR fungible token from the +balance owned by the funding account. + +An allowance SHALL NOT transfer any tokens directly, it only permits +transactions signed only by the spender account to transfer tokens +of the specified type, up to the amount specified, from the funding account. + +Once the specified amount is spent, the allowance SHALL be consumed +and a new allowance SHALL be required before that spending account +may spend additional tokens from the funding account. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| token_id | [TokenID](#proto-TokenID) | | The identifier for the token associated with this allowance.

This token MUST be a fungible/common token. | +| spender | [AccountID](#proto-AccountID) | | The identifier for the spending account associated with this allowance.

This account SHALL be permitted to sign transactions to spend tokens of the associated token type from the funding/allowing account.
This permission SHALL be limited to no more than the specified `amount`. | +| amount | [int64](#int64) | | The maximum amount that the spender account may transfer within the scope of this allowance.

This allowance SHALL be consumed if any combination of transfers authorized via this allowance meet this value in total.
This value MUST be specified in the smallest units of the relevant token (i.e. 10-decimals whole tokens). | + + + + + + + + + + + + + + + diff --git a/documents/api/services/get_by_key.md b/documents/api/services/get_by_key.md new file mode 100644 index 00000000..58a54868 --- /dev/null +++ b/documents/api/services/get_by_key.md @@ -0,0 +1,103 @@ +## Table of Contents + +- [get_by_key.proto](#get_by_key-proto) + - [EntityID](#proto-EntityID) + - [GetByKeyQuery](#proto-GetByKeyQuery) + - [GetByKeyResponse](#proto-GetByKeyResponse) + + + + + +

Top

+ +## get_by_key.proto +# Get By Key +An obsolete query to obtain a list of entities that refer to +a given Key object.
+Returned entities may be accounts, files, smart contracts, and/or +live hash entries. + +> Important +>> This query is obsolete and not supported.
+>> Any query of this type that is submitted SHALL fail with a `PRE_CHECK` +>> result of `NOT_SUPPORTED`. + +> Implementation Note +>> This query is not defined for any service, and while it is implemented +>> in the "Network Admin" service, it may be unnecessary to do so. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### EntityID +The ID for a single entity (account, livehash, file, or smart contract) + +> The query that defines this message is no longer supported. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| accountID | [AccountID](#proto-AccountID) | | The Account ID for the cryptocurrency account | +| liveHash | [LiveHash](#proto-LiveHash) | | A uniquely identifying livehash of an account | +| fileID | [FileID](#proto-FileID) | | The file ID of the file | +| contractID | [ContractID](#proto-ContractID) | | The smart contract ID that identifies instance | + + + + + + + + +### GetByKeyQuery +Query all accounts, claims, files, and smart contract instances whose +associated keys include the given Key. + +> This query is no longer supported. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.
This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither). | +| key | [Key](#proto-Key) | | The key to search for. It MUST NOT contain a contractID nor a ThresholdKey. | + + + + + + + + +### GetByKeyResponse +Response when the client sends the node GetByKeyQuery + +> This query is no longer supported. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| entities | [EntityID](#proto-EntityID) | repeated | The list of entities that include this public key in their associated Key list | + + + + + + + + + + + + + + + diff --git a/documents/api/services/get_by_solidity_id.md b/documents/api/services/get_by_solidity_id.md new file mode 100644 index 00000000..d7db322d --- /dev/null +++ b/documents/api/services/get_by_solidity_id.md @@ -0,0 +1,72 @@ +## Table of Contents + +- [get_by_solidity_id.proto](#get_by_solidity_id-proto) + - [GetBySolidityIDQuery](#proto-GetBySolidityIDQuery) + - [GetBySolidityIDResponse](#proto-GetBySolidityIDResponse) + + + + + +

Top

+ +## get_by_solidity_id.proto +# Get By Solidity +A standard query to obtain account and contract identifiers for a smart +contract, given the Solidity identifier for that contract. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### GetBySolidityIDQuery +Query to read Contract, Account, and File identifiers for a smart +contract given a Solidity identifier. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.
This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither). | +| solidityID | [string](#string) | | A contract ID in the format used by Solidity.

This field is REQUIRED. | + + + + + + + + +### GetBySolidityIDResponse +Response to a getBySolidityId query. + +This message returns the account, contract, and file identifiers for +a smart contract. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| accountID | [AccountID](#proto-AccountID) | | An account identifier.

This SHALL identify an account that backs the requested smart contract. | +| fileID | [FileID](#proto-FileID) | | A file identifier.

This SHALL identify a file, the contents of which are the EVM bytecode for the requested smart contract. | +| contractID | [ContractID](#proto-ContractID) | | A contract identifier.

This SHALL identify the requested smart contract. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/network_get_execution_time.md b/documents/api/services/network_get_execution_time.md new file mode 100644 index 00000000..7f637a1d --- /dev/null +++ b/documents/api/services/network_get_execution_time.md @@ -0,0 +1,88 @@ +## Table of Contents + +- [network_get_execution_time.proto](#network_get_execution_time-proto) + - [NetworkGetExecutionTimeQuery](#proto-NetworkGetExecutionTimeQuery) + - [NetworkGetExecutionTimeResponse](#proto-NetworkGetExecutionTimeResponse) + + + + + +

Top

+ +## network_get_execution_time.proto +# Get Execution Time +Given a list of transaction identifiers, return the time required to +process each transaction, excluding pre-consensus processing, consensus, +and post-processing (e.g. record stream generation). + +> Important +>> This query is obsolete and not supported.
+>> Any query of this type that is submitted SHALL fail with a `PRE_CHECK` +>> result of `NOT_SUPPORTED`. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### NetworkGetExecutionTimeQuery +Retrieve the time, in nanoseconds, spent in direct processing for one +or more recent transactions. + +For each transaction identifier provided, if that transaction is +sufficiently recent (that is, it is within the range of the configuration +value `stats.executionTimesToTrack`), the node SHALL return the time, in +nanoseconds, spent to directly process that transaction.
+This time will generally correspond to the time spent in a `handle` call +within the workflow. + +Note that because each node processes every transaction for the Hedera +network, this query MAY be sent to any node, and results MAY be different +between different nodes. + +> REVIEW NOTE +>> This query is no longer supported. Should we deprecate the messages +>> and service gRPC call? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.
This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither). | +| transaction_ids | [TransactionID](#proto-TransactionID) | repeated | A list of transaction identifiers to query.

All of the queried transaction identifiers MUST have execution time available. If any identifier does not have available execution time, the query SHALL fail with an `INVALID_TRANSACTION_ID` response. | + + + + + + + + +### NetworkGetExecutionTimeResponse +A response to a `networkGetExecutionTime` query. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| execution_times | [uint64](#uint64) | repeated | A list of execution times, in nanoseconds.

This list SHALL be in the same order as the transaction identifiers were presented in the query. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/network_get_version_info.md b/documents/api/services/network_get_version_info.md new file mode 100644 index 00000000..a66f35fd --- /dev/null +++ b/documents/api/services/network_get_version_info.md @@ -0,0 +1,72 @@ +## Table of Contents + +- [network_get_version_info.proto](#network_get_version_info-proto) + - [NetworkGetVersionInfoQuery](#proto-NetworkGetVersionInfoQuery) + - [NetworkGetVersionInfoResponse](#proto-NetworkGetVersionInfoResponse) + + + + + +

Top

+ +## network_get_version_info.proto +# Get Version +Standard query for services and API message versions. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### NetworkGetVersionInfoQuery +Query the deployed versions of Hedera Services and the API definitions in +semantic version format + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.
This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither). | + + + + + + + + +### NetworkGetVersionInfoResponse +A response to a `NetworkGetVersionInfoQuery`. + +This SHALL return `SemanticVersion` information for both Hedera API (HAPI) +and Hedera Services. + +> Note that the Hedera software MAY use the fields of the `SemanticVersion` +> in a somewhat unorthodox manner. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| hapiProtoVersion | [SemanticVersion](#proto-SemanticVersion) | | An API version.

This SHALL be the current Hedera API (HAPI) protobuf message version accepted by the network. | +| hederaServicesVersion | [SemanticVersion](#proto-SemanticVersion) | | A Services version.

This SHALL be the current version of the Hedera Services software operating the network. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/network_service.md b/documents/api/services/network_service.md new file mode 100644 index 00000000..7d16af4c --- /dev/null +++ b/documents/api/services/network_service.md @@ -0,0 +1,48 @@ +## Table of Contents + +- [network_service.proto](#network_service-proto) + - [NetworkService](#proto-NetworkService) + + + + + +

Top

+ +## network_service.proto +# Network Service +This service offers some basic "network information" queries. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + + + + + + + +### NetworkService +Basic "network information" queries. + +This service supports queries for the active services and API versions, +and a query for account details. + +| Method Name | Request Type | Response Type | Description | +| ----------- | ------------ | ------------- | ------------| +| getVersionInfo | [Query](#proto-Query) | [Response](#proto-Response) | Retrieve the active versions of Hedera Services and API messages. | +| getAccountDetails | [Query](#proto-Query) | [Response](#proto-Response) | Request detail information about an account.

The returned information SHALL include balance and allowances.
The returned information SHALL NOT include a list of account records. | +| getExecutionTime | [Query](#proto-Query) | [Response](#proto-Response) | Retrieve the time, in nanoseconds, spent in direct processing for one or more recent transactions.

For each transaction identifier provided, if that transaction is sufficiently recent (that is, it is within the range of the configuration value `stats.executionTimesToTrack`), the node SHALL return the time, in nanoseconds, spent to directly process that transaction (that is, excluding time to reach consensus).
Note that because each node processes every transaction for the Hedera network, this query MAY be sent to any node.

Important
This query is obsolete, not supported, and SHALL fail with a pre-check result of `NOT_SUPPORTED`.
| +| uncheckedSubmit | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Submit a transaction that wraps another transaction which will skip most validation.

Important
This transaction SHALL NOT, under any circumstances, be enabled in mainnet.
The `uncheckedSubmit` transaction SHALL NOT be accepted unless signed by the `treasury` account or the `systemAdmin` account.
| + + + + + diff --git a/documents/api/services/node_create.md b/documents/api/services/node_create.md new file mode 100644 index 00000000..3cd13242 --- /dev/null +++ b/documents/api/services/node_create.md @@ -0,0 +1,69 @@ +## Table of Contents + +- [node_create.proto](#node_create-proto) + - [NodeCreateTransactionBody](#com-hedera-hapi-node-addressbook-NodeCreateTransactionBody) + + + + + +

Top

+ +## node_create.proto + + + + + +### NodeCreateTransactionBody +A transaction body to add a new consensus node to the network address book. + +This transaction body SHALL be considered a "privileged transaction". + +This message supports a transaction to create a new node in the network +address book. The transaction, once complete, enables a new consensus node +to join the network, and requires governing council authorization. + +- A `NodeCreateTransactionBody` MUST be signed by the governing council. +- A `NodeCreateTransactionBody` MUST be signed by the `Key` assigned to the + `admin_key` field. +- The newly created node information SHALL be added to the network address + book information in the network state. +- The new entry SHALL be created in "state" but SHALL NOT participate in + network consensus and SHALL NOT be present in network "configuration" + until the next "upgrade" transaction (as noted below). +- All new address book entries SHALL be added to the active network + configuration during the next `freeze` transaction with the field + `freeze_type` set to `PREPARE_UPGRADE`. + +### Record Stream Effects +Upon completion the newly assigned `node_id` SHALL be recorded in +the transaction receipt.
+This value SHALL be the next available node identifier.
+Node identifiers SHALL NOT be reused. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| account_id | [proto.AccountID](#proto-AccountID) | | A Node account identifier.

This account identifier MUST be in the "account number" form.
This account identifier MUST NOT use the alias field.
If the identified account does not exist, this transaction SHALL fail.
Multiple nodes MAY share the same node account.
This field is REQUIRED. | +| description | [string](#string) | | A short description of the node.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8.
This field is OPTIONAL. | +| gossip_endpoint | [proto.ServiceEndpoint](#proto-ServiceEndpoint) | repeated | A list of service endpoints for gossip.

These endpoints SHALL represent the published endpoints to which other consensus nodes may _gossip_ transactions.
These endpoints MUST specify a port.
This list MUST NOT be empty.
This list MUST NOT contain more than `10` entries.
The first two entries in this list SHALL be the endpoints published to all consensus nodes.
All other entries SHALL be reserved for future use.

Each network may have additional requirements for these endpoints. A client MUST check network-specific documentation for those details.
If the network configuration value `gossipFqdnRestricted` is set, then all endpoints in this list MUST supply only IP address.
If the network configuration value `gossipFqdnRestricted` is _not_ set, then endpoints in this list MAY supply either IP address or FQDN, but MUST NOT supply both values for the same endpoint. | +| service_endpoint | [proto.ServiceEndpoint](#proto-ServiceEndpoint) | repeated | A list of service endpoints for gRPC calls.

These endpoints SHALL represent the published gRPC endpoints to which clients may submit transactions.
These endpoints MUST specify a port.
Endpoints in this list MAY supply either IP address or FQDN, but MUST NOT supply both values for the same endpoint.
This list MUST NOT be empty.
This list MUST NOT contain more than `8` entries. | +| gossip_ca_certificate | [bytes](#bytes) | | A certificate used to sign gossip events.

This value MUST be a certificate of a type permitted for gossip signatures.
This value MUST be the DER encoding of the certificate presented.
This field is REQUIRED and MUST NOT be empty. | +| grpc_certificate_hash | [bytes](#bytes) | | A hash of the node gRPC TLS certificate.

This value MAY be used to verify the certificate presented by the node during TLS negotiation for gRPC.
This value MUST be a SHA-384 hash.
The TLS certificate to be hashed MUST first be in PEM format and MUST be encoded with UTF-8 NFKD encoding to a stream of bytes provided to the hash algorithm.
This field is OPTIONAL. | +| admin_key | [proto.Key](#proto-Key) | | An administrative key controlled by the node operator.

This key MUST sign this transaction.
This key MUST sign each transaction to update this node.
This field MUST contain a valid `Key` value.
This field is REQUIRED and MUST NOT be set to an empty `KeyList`. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/node_delete.md b/documents/api/services/node_delete.md new file mode 100644 index 00000000..f77d39c9 --- /dev/null +++ b/documents/api/services/node_delete.md @@ -0,0 +1,54 @@ +## Table of Contents + +- [node_delete.proto](#node_delete-proto) + - [NodeDeleteTransactionBody](#com-hedera-hapi-node-addressbook-NodeDeleteTransactionBody) + + + + + +

Top

+ +## node_delete.proto + + + + + +### NodeDeleteTransactionBody +A transaction body to delete a node from the network address book. + +This transaction body SHALL be considered a "privileged transaction". + +- A `NodeDeleteTransactionBody` MUST be signed by the governing council. +- Upon success, the address book entry SHALL enter a "pending delete" + state. +- All address book entries pending deletion SHALL be removed from the + active network configuration during the next `freeze` transaction with + the field `freeze_type` set to `PREPARE_UPGRADE`.
+- A deleted address book node SHALL be removed entirely from network state. +- A deleted address book node identifier SHALL NOT be reused. + +### Record Stream Effects +Upon completion the "deleted" `node_id` SHALL be in the transaction +receipt. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| node_id | [uint64](#uint64) | | A consensus node identifier in the network state.

The node identified MUST exist in the network address book.
The node identified MUST NOT be deleted.
This value is REQUIRED. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/node_get_info.md b/documents/api/services/node_get_info.md new file mode 100644 index 00000000..1c91a872 --- /dev/null +++ b/documents/api/services/node_get_info.md @@ -0,0 +1,96 @@ +## Table of Contents + +- [node_get_info.proto](#node_get_info-proto) + - [NodeGetInfoQuery](#com-hedera-hapi-node-addressbook-NodeGetInfoQuery) + - [NodeGetInfoResponse](#com-hedera-hapi-node-addressbook-NodeGetInfoResponse) + - [NodeInfo](#com-hedera-hapi-node-addressbook-NodeInfo) + + + + + +

Top

+ +## node_get_info.proto + + + + + +### NodeGetInfoQuery +A transaction body for a `getNodeInfo ` node information query request. + +This transaction body SHALL be considered a "privileged transaction". + +- A `NodeGetInfoQuery` MUST be signed by the governing council. +- This query requests details for a single consensus node entry in the + network state. +- The node identifier `node_id` is REQUIRED, and identifies the node for + which details are requested. + +> Note +>> Requiring governing council signature for a query like this seems quite +>> unusual. Further detail for _why_ only the governing council is permitted +>> to query this information would be helpful (particularly as the block +>> stream and mirror node make it trivial to obtain the same information). + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [proto.QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.

This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither). | +| node_id | [uint64](#uint64) | | A consensus node identifier for which information is requested.

If the identified node is not valid, this request SHALL fail with a response code `INVALID_NODE_ID`.
If the identified node is not present in the network state, this request SHALL fail with a response code `INVALID_NODE_ID`. | + + + + + + + + +### NodeGetInfoResponse +Response body for a `getNodeInfo` node information query. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [proto.ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| nodeInfo | [NodeInfo](#com-hedera-hapi-node-addressbook-NodeInfo) | | The requested detail information.

This message SHALL contain the full detail for the node identified in the query request. | + + + + + + + + +### NodeInfo +A query response describing the current state of a consensus node entry in +the network state. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| node_id | [uint64](#uint64) | | A consensus node identifier in the network state.

This value identifies this node within the network address book.
This value is REQUIRED. | +| account_id | [proto.AccountID](#proto-AccountID) | | An account identifier.

This account MUST be owned by the entity responsible for the node.
This account SHALL be charged transaction fees for any transactions that are submitted to the network by this node and fail due diligence checks.
This value is REQUIRED. | +| description | [string](#string) | | A short description of the consensus node.

This value, if present, MUST NOT exceed 100 bytes when encoded as UTF-8. | +| gossip_endpoint | [proto.ServiceEndpoint](#proto-ServiceEndpoint) | repeated | A list of service endpoints for gossip.

These endpoints SHALL represent the published endpoints to which other consensus nodes may _gossip_ transactions.
These endpoints SHOULD NOT specify both address and DNS name.
This list SHALL NOT be empty.
This list SHALL NOT contain more than `10` entries.
The first two entries in this list SHALL be the endpoints published to all consensus nodes.
All other entries SHALL be reserved for future use.

Each network may have additional requirements for these endpoints. A client MUST check network-specific documentation for those details.

Example
Hedera Mainnet _requires_ that address be specified, and does not permit DNS name (FQDN) to be specified.
Mainnet also requires that the first entry be an "internal" IP address and the second entry be an "external" IP address.
Solo, however, _requires_ DNS name (FQDN) but also permits address.
| +| service_endpoint | [proto.ServiceEndpoint](#proto-ServiceEndpoint) | repeated | A list of service endpoints for gRPC calls.

These endpoints SHALL represent the published endpoints to which clients may submit transactions.
These endpoints SHOULD specify address and port.
These endpoints MAY specify a DNS name.
These endpoints SHOULD NOT specify both address and DNS name.
This list SHALL NOT be empty.
This list SHALL NOT contain more than `8` entries.

Each network may have additional requirements for these endpoints. A client MUST check network-specific documentation for those details. | +| gossip_ca_certificate | [bytes](#bytes) | | A certificate used to sign gossip events.

This value SHALL be a certificate of a type permitted for gossip signatures.
This value SHALL be the DER encoding of the certificate presented.
This field is REQUIRED and MUST NOT be empty. | +| grpc_certificate_hash | [bytes](#bytes) | | A hash of the node gRPC TLS certificate.

This value MAY be used to verify the certificate presented by the node during TLS negotiation for gRPC.
This value MUST be a SHA-384 hash.
The TLS certificate to be hashed SHALL first be in PEM format and SHALL be encoded with UTF-8 NFKD encoding to a stream of bytes provided to the hash algorithm.
This field is OPTIONAL. | +| weight | [uint64](#uint64) | | A consensus weight.

Each node SHALL have a weight in consensus calculations.
The consensus weight of a node SHALL be calculated based on the amount of HBAR staked to that node.
Consensus SHALL be calculated based on agreement of greater than `2/3` of the total `weight` value of all nodes on the network. | +| deleted | [bool](#bool) | | A flag indicating this node was removed from the network.

This flag SHALL NOT be set unless a `deleteNode` transaction previously succeeded identifying that node.
If this flag is set, the associated node SHALL NOT participate in the network. | +| ledger_id | [bytes](#bytes) | | A ledger ID.

This identifies the network that responded to this query. The specific values are documented in [HIP-198] (https://hips.hedera.com/hip/hip-198). | + + + + + + + + + + + + + + diff --git a/documents/api/services/node_stake_update.md b/documents/api/services/node_stake_update.md new file mode 100644 index 00000000..49f8b74a --- /dev/null +++ b/documents/api/services/node_stake_update.md @@ -0,0 +1,105 @@ +## Table of Contents + +- [node_stake_update.proto](#node_stake_update-proto) + - [NodeStake](#proto-NodeStake) + - [NodeStakeUpdateTransactionBody](#proto-NodeStakeUpdateTransactionBody) + + + + + +

Top

+ +## node_stake_update.proto +# Node Stake Updates +A system-initiated (i.e. internal) transaction to update stake information +for nodes at the end of a staking period. + +Note that staking rewards are not paid immediately. The rewards are +calculated, and the amount to be paid is reserved in the reward account, +at the end of each staking period. The actual recipient accounts are then +paid rewards when that account participates in any transaction that +changes staking information or the account balance. This reduces the +resources for calculating the staking rewards, quite dramatically, +and provides an incentive for account owners to engage with the network, +in at least a minor fashion, occasionally (typically annually).
+The unexpected change in balances, however, can be surprising to the +account holder. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### NodeStake +Staking information for one node at the end of a staking period. + +This SHALL be one entry in a list reported at the end of each +full staking period. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| max_stake | [int64](#int64) | | A limit to the amount of stake considered for consensus weight.

The amount of stake (whether accepting rewards or not) assigned to a node that exceeds this limit SHALL NOT be considered for consensus weight calculation.
If stake to _reward_ for a node exceeds this threshold, then all accounts staking to that node SHALL receive a lower reward rate in proportion to the excess stake. | +| min_stake | [int64](#int64) | | A minimum amount of HBAR staked to a node to receive rewards.

If the amount of stake (whether accepting rewards or not) assigned to a node at the start of a staking period is less than this threshold, then no rewards SHALL be paid to that node or to any accounts staking to that node. | +| node_id | [int64](#int64) | | A node identifier.
This value uniquely identifies this node within the network address book. | +| reward_rate | [int64](#int64) | | The rate of rewards, in tinybar per HBAR, for the staking reward period that just ended. | +| stake | [int64](#int64) | | A consensus weight assigned to this node for the next staking period. | +| stake_not_rewarded | [int64](#int64) | | The total amount staked to this node, while declining rewards.

This SHALL be the total staked amount, in tinybar, that is staked to this node with the value of the `decline_reward` set.
This value MUST be calculated at the beginning of the staking period. | +| stake_rewarded | [int64](#int64) | | The total amount staked to this node, while accepting rewards.

This SHALL be the total staked amount, in tinybar, that is staked to this node with the value of the `decline_reward` not set.
This value MUST be calculated at the beginning of the staking period. | + + + + + + + + +### NodeStakeUpdateTransactionBody +A system initiated transaction to update staking information. + +This transaction SHALL be issued at the end of each staking period to update +node stakes and reward limits.
+This transaction SHALL be a child of the first transaction to reach +consensus following the end of the previous staking period.
+This transaction MUST NOT be sent by a client and SHALL be rejected if +received by any node.
+This transaction SHALL be present in the record stream or block stream. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| end_of_staking_period | [Timestamp](#proto-Timestamp) | | A timestamp indicating the end of the staking period.

This value SHALL be one nanosecond prior to midnight prior to the consensus time of the parent transaction. | +| node_stake | [NodeStake](#proto-NodeStake) | repeated | A list of `NodeStake` entries for each node at the beginning of the new staking period.

This list SHALL have one entry for each node participating in network consensus. | +| max_staking_reward_rate_per_hbar | [int64](#int64) | | A maximum reward rate for this staking period.

This SHALL be a ratio of tinybar to HBAR.
An account SHALL NOT receive a reward greater than the product of this ratio and the total number of HBAR staked by that account. | +| node_reward_fee_fraction | [Fraction](#proto-Fraction) | | A fraction of network and service fees paid to the "node" reward account.
The node staking rewards are paid from the designated reward account `0.0.801`, which receives a fraction of network and service fees for each transaction. This field is the value of that fraction for the last staking period. | +| staking_periods_stored | [int64](#int64) | | A limit to the number of staking periods held for inactive accounts.
This is the maximum number of trailing staking periods for which an account can collect staking rewards.

Example

If this value is 365 with a calendar day period, then each account must collect rewards at least once per calendar year to receive the full amount of staking rewards earned.

Staking rewards SHALL be stored in network state for no more than `staking_periods_stored` staking periods.
Each account MUST participate in at least one transaction that affects its balance, staking, or staking metadata within this time limit to receive all available staking rewards. | +| staking_period | [int64](#int64) | | A number of minutes representing a staking period.

Note
For the special case of `1440` minutes, periods are treated as calendar days aligned to midnight UTC, rather than repeating `1440` minute periods left-aligned at the epoch.
| +| staking_reward_fee_fraction | [Fraction](#proto-Fraction) | | A fraction of network and service fees paid to the "general" reward account.
The general staking rewards are paid from the designated reward account `0.0.800`, which receives a fraction of network and service fees for each transaction. This field is the value of that fraction for the last staking period. | +| staking_start_threshold | [int64](#int64) | | A minimum balance required to pay general staking rewards.

If the balance of the staking reward account `0.0.800` is below this threshold, staking rewards SHALL NOT be paid in full. | +| staking_reward_rate | [int64](#int64) | | **Deprecated.** HIP-786 replaced this field with `max_total_reward`.
This was a maximum total number of tinybars to be distributed as staking rewards in the staking period that just ended. | +| reserved_staking_rewards | [int64](#int64) | | An amount reserved in the staking reward account.
This is an amount "reserved" in the balance of account `0.0.800` that is already owed for pending rewards that were previously earned but have not yet been collected.
This value is further detailed in HIP-786. | +| unreserved_staking_reward_balance | [int64](#int64) | | An available, unreserved, amount in the staking reward account.
This is the balance of the staking reward account `0.0.800` at the close of the staking period that just ended, after reduction for all "reserved" funds necessary to pay previously earned rewards.
This value is further detailed in HIP-786.

This value SHALL be used to calculate the reward ratio according to the formula detailed in HIP-782. | +| reward_balance_threshold | [int64](#int64) | | A minimum balance required for maximum staking rewards.
This value is further detailed in HIP-786. The formula to calculate staking rewards is detailed in HIP-782.

The value of `unreserved_staking_reward_balance` MUST match or exceed the value of this field to support the maximum staking reward ratio.
| +| max_stake_rewarded | [int64](#int64) | | A maximum network-wide stake that can earn full rewards.
If the network-wide stake, in tinybar, exceeds this value, then staking rewards must be reduced to maintain "smooth" reward adjustments as defined in HIP-782.
This value is further detailed in HIP-786.

If the total network-wide stake exceeds this value, the effective staking reward ratio MUST be reduced to maintain solvency of the staking reward account. | +| max_total_reward | [int64](#int64) | | A limit amount that could be paid as staking rewards.
In the limit case, the network could pay at most this amount, in tinybar as staking rewards for the staking period that just ended, if all other conditions were met to perfection.

This value SHALL reflect the result of a maximum reward calculation that takes into account the balance thresholds and maximum stake thresholds as defined in HIP-782 and HIP-786.
This value is a convenience. The actual defined calculation SHALL be authoritative in the unlikely event this value differs. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/node_update.md b/documents/api/services/node_update.md new file mode 100644 index 00000000..e8c60bc9 --- /dev/null +++ b/documents/api/services/node_update.md @@ -0,0 +1,65 @@ +## Table of Contents + +- [node_update.proto](#node_update-proto) + - [NodeUpdateTransactionBody](#com-hedera-hapi-node-addressbook-NodeUpdateTransactionBody) + + + + + +

Top

+ +## node_update.proto + + + + + +### NodeUpdateTransactionBody +Transaction body to modify address book node attributes. + +- This transaction SHALL enable the node operator, as identified by the + `admin_key`, to modify operational attributes of the node. +- This transaction MUST be signed by the active `admin_key` for the node. +- If this transaction sets a new value for the `admin_key`, then both the + current `admin_key`, and the new `admin_key` MUST sign this transaction. +- This transaction SHALL NOT change any field that is not set (is null) in + this transaction body. +- This SHALL create a pending update to the node, but the change SHALL NOT + be immediately applied to the active configuration. +- All pending node updates SHALL be applied to the active network + configuration during the next `freeze` transaction with the field + `freeze_type` set to `PREPARE_UPGRADE`. + +### Record Stream Effects +Upon successful completion the `node_id` for the updated entry SHALL be +repeated in the transaction receipt.
+The `node_id` in the transaction receipt SHALL match the `node_id` +provided in the transaction. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| node_id | [uint64](#uint64) | | A consensus node identifier in the network state.

The node identified MUST exist in the network address book.
The node identified MUST NOT be deleted.
This value is REQUIRED. | +| account_id | [proto.AccountID](#proto-AccountID) | | An account identifier.

If set, this SHALL replace the node account identifier.
If set, this transaction MUST be signed by the active `key` for _both_ the current node account _and_ the identified new node account. | +| description | [google.protobuf.StringValue](#google-protobuf-StringValue) | | A short description of the node.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8.
If set, this value SHALL replace the previous value. | +| gossip_endpoint | [proto.ServiceEndpoint](#proto-ServiceEndpoint) | repeated | A list of service endpoints for gossip.

If set, this list MUST meet the following requirements.


These endpoints SHALL represent the published endpoints to which other consensus nodes may _gossip_ transactions.
These endpoints SHOULD NOT specify both address and DNS name.
This list MUST NOT be empty.
This list MUST NOT contain more than `10` entries.
The first two entries in this list SHALL be the endpoints published to all consensus nodes.
All other entries SHALL be reserved for future use.

Each network may have additional requirements for these endpoints. A client MUST check network-specific documentation for those details.

Example
Hedera Mainnet _requires_ that address be specified, and does not permit DNS name (FQDN) to be specified.
Mainnet also requires that the first entry be an "internal" IP address and the second entry be an "external" IP address.
Solo, however, _requires_ DNS name (FQDN) but also permits address.

If set, the new list SHALL replace the existing list. | +| service_endpoint | [proto.ServiceEndpoint](#proto-ServiceEndpoint) | repeated | A list of service endpoints for gRPC calls.

If set, this list MUST meet the following requirements.


These endpoints SHALL represent the published endpoints to which clients may submit transactions.
These endpoints SHOULD specify address and port.
These endpoints MAY specify a DNS name.
These endpoints SHOULD NOT specify both address and DNS name.
This list MUST NOT be empty.
This list MUST NOT contain more than `8` entries.

Each network may have additional requirements for these endpoints. A client MUST check network-specific documentation for those details.

If set, the new list SHALL replace the existing list. | +| gossip_ca_certificate | [google.protobuf.BytesValue](#google-protobuf-BytesValue) | | A certificate used to sign gossip events.

This value MUST be a certificate of a type permitted for gossip signatures.
This value MUST be the DER encoding of the certificate presented.

If set, the new value SHALL replace the existing bytes value. | +| grpc_certificate_hash | [google.protobuf.BytesValue](#google-protobuf-BytesValue) | | A hash of the node gRPC TLS certificate.

This value MAY be used to verify the certificate presented by the node during TLS negotiation for gRPC.
This value MUST be a SHA-384 hash.
The TLS certificate to be hashed MUST first be in PEM format and MUST be encoded with UTF-8 NFKD encoding to a stream of bytes provided to the hash algorithm.

If set, the new value SHALL replace the existing hash value. | +| admin_key | [proto.Key](#proto-Key) | | An administrative key controlled by the node operator.

This field is OPTIONAL.
If set, this key MUST sign this transaction.
If set, this key MUST sign each subsequent transaction to update this node.
If set, this field MUST contain a valid `Key` value.
If set, this field MUST NOT be set to an empty `KeyList`. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/query.md b/documents/api/services/query.md new file mode 100644 index 00000000..1e2f1563 --- /dev/null +++ b/documents/api/services/query.md @@ -0,0 +1,78 @@ +## Table of Contents + +- [query.proto](#query-proto) + - [Query](#proto-Query) + + + + + +

Top

+ +## query.proto +# Query +This is the parent message for all queries, and this message is +serialized and signed, with the signature included in the QueryHeader. + +All of the entries in the `query` `oneof` are fully specified elsewhere; +we only include a short summary here. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### Query +A query transaction.
+This message is serialized to bytes and those bytes are signed by the +submitter, with the signature included in the QueryHeader for the query +request. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| getByKey | [GetByKeyQuery](#proto-GetByKeyQuery) | | Get all entities associated with a given key. | +| getBySolidityID | [GetBySolidityIDQuery](#proto-GetBySolidityIDQuery) | | Get an Hedera identifier associated with an identifier in EVM "Solidity" form.
Most often used in smart contracts to find an Hedera account, file, or contract identifier to pass to a system contract or precompile. | +| contractCallLocal | [ContractCallLocalQuery](#proto-ContractCallLocalQuery) | | Call a function of a smart contract.
This call is executed exclusively on the node to which it is submitted, and is much less expensive than a `contractCall` transaction. | +| contractGetInfo | [ContractGetInfoQuery](#proto-ContractGetInfoQuery) | | Get information about a smart contract. | +| contractGetBytecode | [ContractGetBytecodeQuery](#proto-ContractGetBytecodeQuery) | | Get runtime bytecode used by a smart contract. | +| ContractGetRecords | [ContractGetRecordsQuery](#proto-ContractGetRecordsQuery) | | **Deprecated.** This query is unsupported and SHALL fail.
Requests for this information MUST be directed to a mirror node.

Get Records of a smart contract. | +| cryptogetAccountBalance | [CryptoGetAccountBalanceQuery](#proto-CryptoGetAccountBalanceQuery) | | Get the current HBAR balance of an Hedera account or smart contract. | +| cryptoGetAccountRecords | [CryptoGetAccountRecordsQuery](#proto-CryptoGetAccountRecordsQuery) | | Get records of all "recent" transactions for which a specified account is the effective payer. | +| cryptoGetInfo | [CryptoGetInfoQuery](#proto-CryptoGetInfoQuery) | | Get information about an account, including the balance.
This does not get the list of account records. | +| cryptoGetLiveHash | [CryptoGetLiveHashQuery](#proto-CryptoGetLiveHashQuery) | | **Deprecated.** This query is unsupported and SHALL fail.
Requests for this information MUST be directed to a mirror node.

Get a single livehash from a single account, if present. | +| cryptoGetProxyStakers | [CryptoGetStakersQuery](#proto-CryptoGetStakersQuery) | | **Deprecated.** This query is unsupported and SHALL fail.
Requests for this information MUST be directed to a mirror node.

Get all the accounts that are proxy staking to this account. | +| fileGetContents | [FileGetContentsQuery](#proto-FileGetContentsQuery) | | Get the content of a file. | +| fileGetInfo | [FileGetInfoQuery](#proto-FileGetInfoQuery) | | Get metadata for a file. | +| transactionGetReceipt | [TransactionGetReceiptQuery](#proto-TransactionGetReceiptQuery) | | Get a receipt for a transaction.
This only returns a receipt if the transaction is "recent", which is typically within the previous 180 seconds (3 minutes). | +| transactionGetRecord | [TransactionGetRecordQuery](#proto-TransactionGetRecordQuery) | | Get a record for a transaction. This only returns a record if the transaction is "available", which is typically within the previous 1 hour. | +| transactionGetFastRecord | [TransactionGetFastRecordQuery](#proto-TransactionGetFastRecordQuery) | | Get a record for a transaction. This only returns a record if the transaction is "recent", which is typically within the previous 180 seconds (3 minutes). | +| consensusGetTopicInfo | [ConsensusGetTopicInfoQuery](#proto-ConsensusGetTopicInfoQuery) | | Get metadata for a consensus topic. | +| networkGetVersionInfo | [NetworkGetVersionInfoQuery](#proto-NetworkGetVersionInfoQuery) | | Get the versions of Hedera Services and the HAPI API deployed on the responding consensus node. | +| tokenGetInfo | [TokenGetInfoQuery](#proto-TokenGetInfoQuery) | | Get metadata for a token. | +| scheduleGetInfo | [ScheduleGetInfoQuery](#proto-ScheduleGetInfoQuery) | | Get metadata for a schedule.
A schedule is a request to execute a transaction at a future time. | +| tokenGetAccountNftInfos | [TokenGetAccountNftInfosQuery](#proto-TokenGetAccountNftInfosQuery) | | **Deprecated.** This query is unsupported and SHALL fail.
Requests for this information MUST be directed to a mirror node.

Get a list of non-fungible/unique tokens associated with an account. | +| tokenGetNftInfo | [TokenGetNftInfoQuery](#proto-TokenGetNftInfoQuery) | | Get metadata for a specific, serial numbered, non-fungible/unique token (NFT). | +| tokenGetNftInfos | [TokenGetNftInfosQuery](#proto-TokenGetNftInfosQuery) | | **Deprecated.** This query is unsupported and SHALL fail.
Requests for this information MUST be directed to a mirror node.

Get metadata for all non-fungible/unique tokens (NFTs) of a single type within a range of indices (0-based count of minted tokens). | +| networkGetExecutionTime | [NetworkGetExecutionTimeQuery](#proto-NetworkGetExecutionTimeQuery) | | **Deprecated.** This query is unsupported and SHALL fail.
Requests for this information MUST be directed to a mirror node.

Get the execution time for a recent transaction. | +| accountDetails | [GetAccountDetailsQuery](#proto-GetAccountDetailsQuery) | | Get detail metadata for an account. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/query_header.md b/documents/api/services/query_header.md new file mode 100644 index 00000000..77020fe2 --- /dev/null +++ b/documents/api/services/query_header.md @@ -0,0 +1,81 @@ +## Table of Contents + +- [query_header.proto](#query_header-proto) + - [QueryHeader](#proto-QueryHeader) + + - [ResponseType](#proto-ResponseType) + + + + + +

Top

+ +## query_header.proto +# Query Header +Messages that comprise a header sent with each query request. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### QueryHeader +A standard query header.
+Each query from the client to the node must contain a QueryHeader, which +specifies the desired response type, and includes a payment transaction +that will compensate the network for responding to the query. +The payment may be blank if the query is free. + +The payment transaction MUST be a `cryptoTransfer` from the payer account +to the account of the node where the query is submitted.
+If the payment is sufficient, the network SHALL respond with the response +type requested.
+If the response type is `COST_ANSWER` the payment MUST be unset. +A state proof SHALL be available for some types of information.
+A state proof SHALL be available for a Record, but not a receipt, and the +response entry for each supported "get info" query. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| payment | [Transaction](#proto-Transaction) | | A signed `CryptoTransferTransaction` to pay query fees.

This MUST transfer HBAR from the "payer" to the responding node account sufficient to pay the query fees. | +| responseType | [ResponseType](#proto-ResponseType) | | A type of query response requested. | + + + + + + + + + + +### ResponseType +The type of query response.
+ +This SHALL be answer-only as a default.
+This value SHALL support an "estimated cost" type.
+This value SHOULD support a "state proof" type, when available. + +| Name | Number | Description | +| ---- | ------ | ----------- | +| ANSWER_ONLY | 0 | A response with the query answer. | +| ANSWER_STATE_PROOF | 1 | A response with both the query answer and a state proof. | +| COST_ANSWER | 2 | A response with the estimated cost to answer the query. | +| COST_ANSWER_STATE_PROOF | 3 | A response with the estimated cost to answer and a state proof. | + + + + + + + + + + diff --git a/documents/api/services/response.md b/documents/api/services/response.md new file mode 100644 index 00000000..63da1a3a --- /dev/null +++ b/documents/api/services/response.md @@ -0,0 +1,76 @@ +## Table of Contents + +- [response.proto](#response-proto) + - [Response](#proto-Response) + + + + + +

Top

+ +## response.proto +# Query Response +The `Response` message is returned from a query transaction. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### Response +A single query response. + +Each query MUST define its specific response type.
+Each query response MUST include both the information request and a +`ResponseHeader`.
+All possible query response types MUST be listed here in a `oneof`. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| getByKey | [GetByKeyResponse](#proto-GetByKeyResponse) | | A response for a query requesting all accounts, claims, files, and smart contract instances whose associated keys include the given Key.

> This query is no longer supported. | +| getBySolidityID | [GetBySolidityIDResponse](#proto-GetBySolidityIDResponse) | | A response for a query requesting Contract, Account, and File identifiers for a smart contract, given a Solidity identifier. | +| contractCallLocal | [ContractCallLocalResponse](#proto-ContractCallLocalResponse) | | A response for a _local_ call to a query function of a given smart contract, providing function parameter inputs as needed.

> This call is only performed on the local node. It is _not_ a > network consensus result. | +| contractGetBytecodeResponse | [ContractGetBytecodeResponse](#proto-ContractGetBytecodeResponse) | | A response for a query requesting the current bytecode for a smart contract. | +| contractGetInfo | [ContractGetInfoResponse](#proto-ContractGetInfoResponse) | | A response for a query requesting detailed information about a smart contract. | +| contractGetRecordsResponse | [ContractGetRecordsResponse](#proto-ContractGetRecordsResponse) | | A response for a query requesting records of all transactions against the given contract in the last 25 hours.

> This query is no longer supported. | +| cryptogetAccountBalance | [CryptoGetAccountBalanceResponse](#proto-CryptoGetAccountBalanceResponse) | | A response for a query requesting the HBAR balance of an account or contract. | +| cryptoGetAccountRecords | [CryptoGetAccountRecordsResponse](#proto-CryptoGetAccountRecordsResponse) | | A response for a query requesting records of all "recent" transactions for which the specified account is the effective payer. | +| cryptoGetInfo | [CryptoGetInfoResponse](#proto-CryptoGetInfoResponse) | | A response for a query requesting information for an account.
This query includes balance, but not allowances or token relationships. | +| cryptoGetLiveHash | [CryptoGetLiveHashResponse](#proto-CryptoGetLiveHashResponse) | | A response for a query requesting detail for a specific live hash associated to a specific account.

> This query is no longer supported. | +| cryptoGetProxyStakers | [CryptoGetStakersResponse](#proto-CryptoGetStakersResponse) | | A response for a query requesting all the accounts that are proxy staking to this account.

> This query is no longer supported. | +| fileGetContents | [FileGetContentsResponse](#proto-FileGetContentsResponse) | | A response for a query requesting the content of a file in the Hedera File Service (HFS). | +| fileGetInfo | [FileGetInfoResponse](#proto-FileGetInfoResponse) | | A response for a query requesting file metadata from the Hedera File Service (HFS). | +| transactionGetReceipt | [TransactionGetReceiptResponse](#proto-TransactionGetReceiptResponse) | | A response for a query requesting the post-consensus (final) result of a transaction. | +| transactionGetRecord | [TransactionGetRecordResponse](#proto-TransactionGetRecordResponse) | | A response for a query requesting a transaction record; the detail changes completed in response to a transaction. | +| transactionGetFastRecord | [TransactionGetFastRecordResponse](#proto-TransactionGetFastRecordResponse) | | A response for a query requesting a very recent transaction record.

> This query is no longer supported. | +| consensusGetTopicInfo | [ConsensusGetTopicInfoResponse](#proto-ConsensusGetTopicInfoResponse) | | A response for a query requesting the current state of a topic for the Hedera Consensus Service (HCS). | +| networkGetVersionInfo | [NetworkGetVersionInfoResponse](#proto-NetworkGetVersionInfoResponse) | | A response for a query requesting the deployed versions of Hedera Services and the API definitions in semantic version format | +| tokenGetInfo | [TokenGetInfoResponse](#proto-TokenGetInfoResponse) | | A response for a query requesting metadata for a specific Token. | +| scheduleGetInfo | [ScheduleGetInfoResponse](#proto-ScheduleGetInfoResponse) | | A response for a query requesting detail for a scheduled transaction. | +| tokenGetAccountNftInfos | [TokenGetAccountNftInfosResponse](#proto-TokenGetAccountNftInfosResponse) | | A response for a query requesting detail for a subset of individual non-fungible/unique tokens owned by an account.
The requested tokens are selected by a list index, which is based on the order in which the tokens were added to the account. | +| tokenGetNftInfo | [TokenGetNftInfoResponse](#proto-TokenGetNftInfoResponse) | | A response for a query requesting detail for a specific non-fungible/unique token selected by both token identifier and serial number. | +| tokenGetNftInfos | [TokenGetNftInfosResponse](#proto-TokenGetNftInfosResponse) | | A response for a query requesting detail for a subset of individual non-fungible/unique tokens.
The requested tokens are selected by a list index, which is based on the order in which the tokens were minted. | +| networkGetExecutionTime | [NetworkGetExecutionTimeResponse](#proto-NetworkGetExecutionTimeResponse) | | A response for a query requesting the time, in nanoseconds, spent in direct processing for one or more recent transactions.

> This query is no longer supported. | +| accountDetails | [GetAccountDetailsResponse](#proto-GetAccountDetailsResponse) | | A response for a query requesting detail information about an account.

This query is a privileged query and "system" account authorization is REQUIRED for this query. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/response_code.md b/documents/api/services/response_code.md new file mode 100644 index 00000000..960df80b --- /dev/null +++ b/documents/api/services/response_code.md @@ -0,0 +1,370 @@ +## Table of Contents + +- [response_code.proto](#response_code-proto) + - [ResponseCodeEnum](#proto-ResponseCodeEnum) + + + + + +

Top

+ +## response_code.proto +# Response Code Enumeration +An enumeration of possible response codes. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + + + +### ResponseCodeEnum +An enumeration of possible response codes. + +| Name | Number | Description | +| ---- | ------ | ----------- | +| OK | 0 | The transaction passed the precheck validations. | +| INVALID_TRANSACTION | 1 | For any error not handled by specific error codes listed below. | +| PAYER_ACCOUNT_NOT_FOUND | 2 | Payer account does not exist. | +| INVALID_NODE_ACCOUNT | 3 | Node Account provided does not match the node account of the node the transaction was submitted to. | +| TRANSACTION_EXPIRED | 4 | Pre-Check error when TransactionValidStart + transactionValidDuration is less than current consensus time. | +| INVALID_TRANSACTION_START | 5 | Transaction start time is greater than current consensus time | +| INVALID_TRANSACTION_DURATION | 6 | The given transactionValidDuration was either non-positive, or greater than the maximum valid duration of 180 secs. | +| INVALID_SIGNATURE | 7 | The transaction signature is not valid | +| MEMO_TOO_LONG | 8 | Transaction memo size exceeded 100 bytes | +| INSUFFICIENT_TX_FEE | 9 | The fee provided in the transaction is insufficient for this type of transaction | +| INSUFFICIENT_PAYER_BALANCE | 10 | The payer account has insufficient cryptocurrency to pay the transaction fee | +| DUPLICATE_TRANSACTION | 11 | This transaction ID is a duplicate of one that was submitted to this node or reached consensus in the last 180 seconds (receipt period) | +| BUSY | 12 | If API is throttled out | +| NOT_SUPPORTED | 13 | The API is not currently supported | +| INVALID_FILE_ID | 14 | The file id is invalid or does not exist | +| INVALID_ACCOUNT_ID | 15 | The account id is invalid or does not exist | +| INVALID_CONTRACT_ID | 16 | The contract id is invalid or does not exist | +| INVALID_TRANSACTION_ID | 17 | Transaction id is not valid | +| RECEIPT_NOT_FOUND | 18 | Receipt for given transaction id does not exist | +| RECORD_NOT_FOUND | 19 | Record for given transaction id does not exist | +| INVALID_SOLIDITY_ID | 20 | The solidity id is invalid or entity with this solidity id does not exist | +| UNKNOWN | 21 | The responding node has submitted the transaction to the network. Its final status is still unknown. | +| SUCCESS | 22 | The transaction succeeded | +| FAIL_INVALID | 23 | There was a system error and the transaction failed because of invalid request parameters. | +| FAIL_FEE | 24 | There was a system error while performing fee calculation, reserved for future. | +| FAIL_BALANCE | 25 | There was a system error while performing balance checks, reserved for future. | +| KEY_REQUIRED | 26 | Key not provided in the transaction body | +| BAD_ENCODING | 27 | Unsupported algorithm/encoding used for keys in the transaction | +| INSUFFICIENT_ACCOUNT_BALANCE | 28 | When the account balance is not sufficient for the transfer | +| INVALID_SOLIDITY_ADDRESS | 29 | During an update transaction when the system is not able to find the Users Solidity address | +| INSUFFICIENT_GAS | 30 | Not enough gas was supplied to execute transaction | +| CONTRACT_SIZE_LIMIT_EXCEEDED | 31 | contract byte code size is over the limit | +| LOCAL_CALL_MODIFICATION_EXCEPTION | 32 | local execution (query) is requested for a function which changes state | +| CONTRACT_REVERT_EXECUTED | 33 | Contract REVERT OPCODE executed | +| CONTRACT_EXECUTION_EXCEPTION | 34 | For any contract execution related error not handled by specific error codes listed above. | +| INVALID_RECEIVING_NODE_ACCOUNT | 35 | In Query validation, account with +ve(amount) value should be Receiving node account, the receiver account should be only one account in the list | +| MISSING_QUERY_HEADER | 36 | Header is missing in Query request | +| ACCOUNT_UPDATE_FAILED | 37 | The update of the account failed | +| INVALID_KEY_ENCODING | 38 | Provided key encoding was not supported by the system | +| NULL_SOLIDITY_ADDRESS | 39 | null solidity address | +| CONTRACT_UPDATE_FAILED | 40 | update of the contract failed | +| INVALID_QUERY_HEADER | 41 | the query header is invalid | +| INVALID_FEE_SUBMITTED | 42 | Invalid fee submitted | +| INVALID_PAYER_SIGNATURE | 43 | Payer signature is invalid | +| KEY_NOT_PROVIDED | 44 | The keys were not provided in the request. | +| INVALID_EXPIRATION_TIME | 45 | Expiration time provided in the transaction was invalid. | +| NO_WACL_KEY | 46 | WriteAccess Control Keys are not provided for the file | +| FILE_CONTENT_EMPTY | 47 | The contents of file are provided as empty. | +| INVALID_ACCOUNT_AMOUNTS | 48 | The crypto transfer credit and debit do not sum equal to 0 | +| EMPTY_TRANSACTION_BODY | 49 | Transaction body provided is empty | +| INVALID_TRANSACTION_BODY | 50 | Invalid transaction body provided | +| INVALID_SIGNATURE_TYPE_MISMATCHING_KEY | 51 | the type of key (base ed25519 key, KeyList, or ThresholdKey) does not match the type of signature (base ed25519 signature, SignatureList, or ThresholdKeySignature) | +| INVALID_SIGNATURE_COUNT_MISMATCHING_KEY | 52 | the number of key (KeyList, or ThresholdKey) does not match that of signature (SignatureList, or ThresholdKeySignature). e.g. if a keyList has 3 base keys, then the corresponding signatureList should also have 3 base signatures. | +| EMPTY_LIVE_HASH_BODY | 53 | the livehash body is empty | +| EMPTY_LIVE_HASH | 54 | the livehash data is missing | +| EMPTY_LIVE_HASH_KEYS | 55 | the keys for a livehash are missing | +| INVALID_LIVE_HASH_SIZE | 56 | the livehash data is not the output of a SHA-384 digest | +| EMPTY_QUERY_BODY | 57 | the query body is empty | +| EMPTY_LIVE_HASH_QUERY | 58 | the crypto livehash query is empty | +| LIVE_HASH_NOT_FOUND | 59 | the livehash is not present | +| ACCOUNT_ID_DOES_NOT_EXIST | 60 | the account id passed has not yet been created. | +| LIVE_HASH_ALREADY_EXISTS | 61 | the livehash already exists for a given account | +| INVALID_FILE_WACL | 62 | File WACL keys are invalid | +| SERIALIZATION_FAILED | 63 | Serialization failure | +| TRANSACTION_OVERSIZE | 64 | The size of the Transaction is greater than transactionMaxBytes | +| TRANSACTION_TOO_MANY_LAYERS | 65 | The Transaction has more than 50 levels | +| CONTRACT_DELETED | 66 | Contract is marked as deleted | +| PLATFORM_NOT_ACTIVE | 67 | the platform node is either disconnected or lagging behind. | +| KEY_PREFIX_MISMATCH | 68 | one public key matches more than one prefixes on the signature map | +| PLATFORM_TRANSACTION_NOT_CREATED | 69 | transaction not created by platform due to large backlog | +| INVALID_RENEWAL_PERIOD | 70 | auto renewal period is not a positive number of seconds | +| INVALID_PAYER_ACCOUNT_ID | 71 | the response code when a smart contract id is passed for a crypto API request | +| ACCOUNT_DELETED | 72 | the account has been marked as deleted | +| FILE_DELETED | 73 | the file has been marked as deleted | +| ACCOUNT_REPEATED_IN_ACCOUNT_AMOUNTS | 74 | same accounts repeated in the transfer account list | +| SETTING_NEGATIVE_ACCOUNT_BALANCE | 75 | attempting to set negative balance value for crypto account | +| OBTAINER_REQUIRED | 76 | when deleting smart contract that has crypto balance either transfer account or transfer smart contract is required | +| OBTAINER_SAME_CONTRACT_ID | 77 | when deleting smart contract that has crypto balance you can not use the same contract id as transferContractId as the one being deleted | +| OBTAINER_DOES_NOT_EXIST | 78 | transferAccountId or transferContractId specified for contract delete does not exist | +| MODIFYING_IMMUTABLE_CONTRACT | 79 | attempting to modify (update or delete a immutable smart contract, i.e. one created without a admin key) | +| FILE_SYSTEM_EXCEPTION | 80 | Unexpected exception thrown by file system functions | +| AUTORENEW_DURATION_NOT_IN_RANGE | 81 | the duration is not a subset of [MINIMUM_AUTORENEW_DURATION,MAXIMUM_AUTORENEW_DURATION] | +| ERROR_DECODING_BYTESTRING | 82 | Decoding the smart contract binary to a byte array failed. Check that the input is a valid hex string. | +| CONTRACT_FILE_EMPTY | 83 | File to create a smart contract was of length zero | +| CONTRACT_BYTECODE_EMPTY | 84 | Bytecode for smart contract is of length zero | +| INVALID_INITIAL_BALANCE | 85 | Attempt to set negative initial balance | +| INVALID_RECEIVE_RECORD_THRESHOLD | 86 | Attempt to set negative receive record threshold | +| INVALID_SEND_RECORD_THRESHOLD | 87 | Attempt to set negative send record threshold | +| ACCOUNT_IS_NOT_GENESIS_ACCOUNT | 88 | Special Account Operations should be performed by only Genesis account, return this code if it is not Genesis Account | +| PAYER_ACCOUNT_UNAUTHORIZED | 89 | The fee payer account doesn't have permission to submit such Transaction | +| INVALID_FREEZE_TRANSACTION_BODY | 90 | FreezeTransactionBody is invalid | +| FREEZE_TRANSACTION_BODY_NOT_FOUND | 91 | FreezeTransactionBody does not exist | +| TRANSFER_LIST_SIZE_LIMIT_EXCEEDED | 92 | Exceeded the number of accounts (both from and to) allowed for crypto transfer list | +| RESULT_SIZE_LIMIT_EXCEEDED | 93 | Smart contract result size greater than specified maxResultSize | +| NOT_SPECIAL_ACCOUNT | 94 | The payer account is not a special account(account 0.0.55) | +| CONTRACT_NEGATIVE_GAS | 95 | Negative gas was offered in smart contract call | +| CONTRACT_NEGATIVE_VALUE | 96 | Negative value / initial balance was specified in a smart contract call / create | +| INVALID_FEE_FILE | 97 | Failed to update fee file | +| INVALID_EXCHANGE_RATE_FILE | 98 | Failed to update exchange rate file | +| INSUFFICIENT_LOCAL_CALL_GAS | 99 | Payment tendered for contract local call cannot cover both the fee and the gas | +| ENTITY_NOT_ALLOWED_TO_DELETE | 100 | Entities with Entity ID below 1000 are not allowed to be deleted | +| AUTHORIZATION_FAILED | 101 | Violating one of these rules: 1) treasury account can update all entities below 0.0.1000, 2) account 0.0.50 can update all entities from 0.0.51 - 0.0.80, 3) Network Function Master Account A/c 0.0.50 - Update all Network Function accounts & perform all the Network Functions listed below, 4) Network Function Accounts: i) A/c 0.0.55 - Update Address Book files (0.0.101/102), ii) A/c 0.0.56 - Update Fee schedule (0.0.111), iii) A/c 0.0.57 - Update Exchange Rate (0.0.112). | +| FILE_UPLOADED_PROTO_INVALID | 102 | Fee Schedule Proto uploaded but not valid (append or update is required) | +| FILE_UPLOADED_PROTO_NOT_SAVED_TO_DISK | 103 | Fee Schedule Proto uploaded but not valid (append or update is required) | +| FEE_SCHEDULE_FILE_PART_UPLOADED | 104 | Fee Schedule Proto File Part uploaded | +| EXCHANGE_RATE_CHANGE_LIMIT_EXCEEDED | 105 | The change on Exchange Rate exceeds Exchange_Rate_Allowed_Percentage | +| MAX_CONTRACT_STORAGE_EXCEEDED | 106 | Contract permanent storage exceeded the currently allowable limit | +| TRANSFER_ACCOUNT_SAME_AS_DELETE_ACCOUNT | 107 | Transfer Account should not be same as Account to be deleted | +| TOTAL_LEDGER_BALANCE_INVALID | 108 | | +| EXPIRATION_REDUCTION_NOT_ALLOWED | 110 | The expiration date/time on a smart contract may not be reduced | +| MAX_GAS_LIMIT_EXCEEDED | 111 | Gas exceeded currently allowable gas limit per transaction | +| MAX_FILE_SIZE_EXCEEDED | 112 | File size exceeded the currently allowable limit | +| RECEIVER_SIG_REQUIRED | 113 | When a valid signature is not provided for operations on account with receiverSigRequired=true | +| INVALID_TOPIC_ID | 150 | The Topic ID specified is not in the system. | +| INVALID_ADMIN_KEY | 155 | A provided admin key was invalid. Verify the bytes for an Ed25519 public key are exactly 32 bytes; and the bytes for a compressed ECDSA(secp256k1) key are exactly 33 bytes, with the first byte either 0x02 or 0x03.. | +| INVALID_SUBMIT_KEY | 156 | A provided submit key was invalid. | +| UNAUTHORIZED | 157 | An attempted operation was not authorized (ie - a deleteTopic for a topic with no adminKey). | +| INVALID_TOPIC_MESSAGE | 158 | A ConsensusService message is empty. | +| INVALID_AUTORENEW_ACCOUNT | 159 | The autoRenewAccount specified is not a valid, active account. | +| AUTORENEW_ACCOUNT_NOT_ALLOWED | 160 | An adminKey was not specified on the topic, so there must not be an autoRenewAccount. | +| TOPIC_EXPIRED | 162 | The topic has expired, was not automatically renewed, and is in a 7 day grace period before the topic will be deleted unrecoverably. This error response code will not be returned until autoRenew functionality is supported by HAPI. | +| INVALID_CHUNK_NUMBER | 163 | chunk number must be from 1 to total (chunks) inclusive. | +| INVALID_CHUNK_TRANSACTION_ID | 164 | For every chunk, the payer account that is part of initialTransactionID must match the Payer Account of this transaction. The entire initialTransactionID should match the transactionID of the first chunk, but this is not checked or enforced by Hedera except when the chunk number is 1. | +| ACCOUNT_FROZEN_FOR_TOKEN | 165 | Account is frozen and cannot transact with the token | +| TOKENS_PER_ACCOUNT_LIMIT_EXCEEDED | 166 | An involved account already has more than tokens.maxPerAccount associations with non-deleted tokens. | +| INVALID_TOKEN_ID | 167 | The token is invalid or does not exist | +| INVALID_TOKEN_DECIMALS | 168 | Invalid token decimals | +| INVALID_TOKEN_INITIAL_SUPPLY | 169 | Invalid token initial supply | +| INVALID_TREASURY_ACCOUNT_FOR_TOKEN | 170 | Treasury Account does not exist or is deleted | +| INVALID_TOKEN_SYMBOL | 171 | Token Symbol is not UTF-8 capitalized alphabetical string | +| TOKEN_HAS_NO_FREEZE_KEY | 172 | Freeze key is not set on token | +| TRANSFERS_NOT_ZERO_SUM_FOR_TOKEN | 173 | Amounts in transfer list are not net zero | +| MISSING_TOKEN_SYMBOL | 174 | A token symbol was not provided | +| TOKEN_SYMBOL_TOO_LONG | 175 | The provided token symbol was too long | +| ACCOUNT_KYC_NOT_GRANTED_FOR_TOKEN | 176 | KYC must be granted and account does not have KYC granted | +| TOKEN_HAS_NO_KYC_KEY | 177 | KYC key is not set on token | +| INSUFFICIENT_TOKEN_BALANCE | 178 | Token balance is not sufficient for the transaction | +| TOKEN_WAS_DELETED | 179 | Token transactions cannot be executed on deleted token | +| TOKEN_HAS_NO_SUPPLY_KEY | 180 | Supply key is not set on token | +| TOKEN_HAS_NO_WIPE_KEY | 181 | Wipe key is not set on token | +| INVALID_TOKEN_MINT_AMOUNT | 182 | The requested token mint amount would cause an invalid total supply | +| INVALID_TOKEN_BURN_AMOUNT | 183 | The requested token burn amount would cause an invalid total supply | +| TOKEN_NOT_ASSOCIATED_TO_ACCOUNT | 184 | A required token-account relationship is missing | +| CANNOT_WIPE_TOKEN_TREASURY_ACCOUNT | 185 | The target of a wipe operation was the token treasury account | +| INVALID_KYC_KEY | 186 | The provided KYC key was invalid. | +| INVALID_WIPE_KEY | 187 | The provided wipe key was invalid. | +| INVALID_FREEZE_KEY | 188 | The provided freeze key was invalid. | +| INVALID_SUPPLY_KEY | 189 | The provided supply key was invalid. | +| MISSING_TOKEN_NAME | 190 | Token Name is not provided | +| TOKEN_NAME_TOO_LONG | 191 | Token Name is too long | +| INVALID_WIPING_AMOUNT | 192 | The provided wipe amount must not be negative, zero or bigger than the token holder balance | +| TOKEN_IS_IMMUTABLE | 193 | Token does not have Admin key set, thus update/delete transactions cannot be performed | +| TOKEN_ALREADY_ASSOCIATED_TO_ACCOUNT | 194 | An associateToken operation specified a token already associated to the account | +| TRANSACTION_REQUIRES_ZERO_TOKEN_BALANCES | 195 | An attempted operation is invalid until all token balances for the target account are zero | +| ACCOUNT_IS_TREASURY | 196 | An attempted operation is invalid because the account is a treasury | +| TOKEN_ID_REPEATED_IN_TOKEN_LIST | 197 | Same TokenIDs present in the token list | +| TOKEN_TRANSFER_LIST_SIZE_LIMIT_EXCEEDED | 198 | Exceeded the number of token transfers (both from and to) allowed for token transfer list | +| EMPTY_TOKEN_TRANSFER_BODY | 199 | TokenTransfersTransactionBody has no TokenTransferList | +| EMPTY_TOKEN_TRANSFER_ACCOUNT_AMOUNTS | 200 | TokenTransfersTransactionBody has a TokenTransferList with no AccountAmounts | +| INVALID_SCHEDULE_ID | 201 | The Scheduled entity does not exist; or has now expired, been deleted, or been executed | +| SCHEDULE_IS_IMMUTABLE | 202 | The Scheduled entity cannot be modified. Admin key not set | +| INVALID_SCHEDULE_PAYER_ID | 203 | The provided Scheduled Payer does not exist | +| INVALID_SCHEDULE_ACCOUNT_ID | 204 | The Schedule Create Transaction TransactionID account does not exist | +| NO_NEW_VALID_SIGNATURES | 205 | The provided sig map did not contain any new valid signatures from required signers of the scheduled transaction | +| UNRESOLVABLE_REQUIRED_SIGNERS | 206 | The required signers for a scheduled transaction cannot be resolved, for example because they do not exist or have been deleted | +| SCHEDULED_TRANSACTION_NOT_IN_WHITELIST | 207 | Only whitelisted transaction types may be scheduled | +| SOME_SIGNATURES_WERE_INVALID | 208 | At least one of the signatures in the provided sig map did not represent a valid signature for any required signer | +| TRANSACTION_ID_FIELD_NOT_ALLOWED | 209 | The scheduled field in the TransactionID may not be set to true | +| IDENTICAL_SCHEDULE_ALREADY_CREATED | 210 | A schedule already exists with the same identifying fields of an attempted ScheduleCreate (that is, all fields other than scheduledPayerAccountID) | +| INVALID_ZERO_BYTE_IN_STRING | 211 | A string field in the transaction has a UTF-8 encoding with the prohibited zero byte | +| SCHEDULE_ALREADY_DELETED | 212 | A schedule being signed or deleted has already been deleted | +| SCHEDULE_ALREADY_EXECUTED | 213 | A schedule being signed or deleted has already been executed | +| MESSAGE_SIZE_TOO_LARGE | 214 | ConsensusSubmitMessage request's message size is larger than allowed. | +| OPERATION_REPEATED_IN_BUCKET_GROUPS | 215 | An operation was assigned to more than one throttle group in a given bucket | +| BUCKET_CAPACITY_OVERFLOW | 216 | The capacity needed to satisfy all opsPerSec groups in a bucket overflowed a signed 8-byte integral type | +| NODE_CAPACITY_NOT_SUFFICIENT_FOR_OPERATION | 217 | Given the network size in the address book, the node-level capacity for an operation would never be enough to accept a single request; usually means a bucket burstPeriod should be increased | +| BUCKET_HAS_NO_THROTTLE_GROUPS | 218 | A bucket was defined without any throttle groups | +| THROTTLE_GROUP_HAS_ZERO_OPS_PER_SEC | 219 | A throttle group was granted zero opsPerSec | +| SUCCESS_BUT_MISSING_EXPECTED_OPERATION | 220 | The throttle definitions file was updated, but some supported operations were not assigned a bucket | +| UNPARSEABLE_THROTTLE_DEFINITIONS | 221 | The new contents for the throttle definitions system file were not valid protobuf | +| INVALID_THROTTLE_DEFINITIONS | 222 | The new throttle definitions system file were invalid, and no more specific error could be divined | +| ACCOUNT_EXPIRED_AND_PENDING_REMOVAL | 223 | The transaction references an account which has passed its expiration without renewal funds available, and currently remains in the ledger only because of the grace period given to expired entities | +| INVALID_TOKEN_MAX_SUPPLY | 224 | Invalid token max supply | +| INVALID_TOKEN_NFT_SERIAL_NUMBER | 225 | Invalid token nft serial number | +| INVALID_NFT_ID | 226 | Invalid nft id | +| METADATA_TOO_LONG | 227 | Nft metadata is too long | +| BATCH_SIZE_LIMIT_EXCEEDED | 228 | Repeated operations count exceeds the limit | +| INVALID_QUERY_RANGE | 229 | The range of data to be gathered is out of the set boundaries | +| FRACTION_DIVIDES_BY_ZERO | 230 | A custom fractional fee set a denominator of zero | +| INSUFFICIENT_PAYER_BALANCE_FOR_CUSTOM_FEE | 231 | The transaction payer could not afford a custom fee | +| CUSTOM_FEES_LIST_TOO_LONG | 232 | More than 10 custom fees were specified | +| INVALID_CUSTOM_FEE_COLLECTOR | 233 | Any of the feeCollector accounts for customFees is invalid | +| INVALID_TOKEN_ID_IN_CUSTOM_FEES | 234 | Any of the token Ids in customFees is invalid | +| TOKEN_NOT_ASSOCIATED_TO_FEE_COLLECTOR | 235 | Any of the token Ids in customFees are not associated to feeCollector | +| TOKEN_MAX_SUPPLY_REACHED | 236 | A token cannot have more units minted due to its configured supply ceiling | +| SENDER_DOES_NOT_OWN_NFT_SERIAL_NO | 237 | The transaction attempted to move an NFT serial number from an account other than its owner | +| CUSTOM_FEE_NOT_FULLY_SPECIFIED | 238 | A custom fee schedule entry did not specify either a fixed or fractional fee | +| CUSTOM_FEE_MUST_BE_POSITIVE | 239 | Only positive fees may be assessed at this time | +| TOKEN_HAS_NO_FEE_SCHEDULE_KEY | 240 | Fee schedule key is not set on token | +| CUSTOM_FEE_OUTSIDE_NUMERIC_RANGE | 241 | A fractional custom fee exceeded the range of a 64-bit signed integer | +| ROYALTY_FRACTION_CANNOT_EXCEED_ONE | 242 | A royalty cannot exceed the total fungible value exchanged for an NFT | +| FRACTIONAL_FEE_MAX_AMOUNT_LESS_THAN_MIN_AMOUNT | 243 | Each fractional custom fee must have its maximum_amount, if specified, at least its minimum_amount | +| CUSTOM_SCHEDULE_ALREADY_HAS_NO_FEES | 244 | A fee schedule update tried to clear the custom fees from a token whose fee schedule was already empty | +| CUSTOM_FEE_DENOMINATION_MUST_BE_FUNGIBLE_COMMON | 245 | Only tokens of type FUNGIBLE_COMMON can be used to as fee schedule denominations | +| CUSTOM_FRACTIONAL_FEE_ONLY_ALLOWED_FOR_FUNGIBLE_COMMON | 246 | Only tokens of type FUNGIBLE_COMMON can have fractional fees | +| INVALID_CUSTOM_FEE_SCHEDULE_KEY | 247 | The provided custom fee schedule key was invalid | +| INVALID_TOKEN_MINT_METADATA | 248 | The requested token mint metadata was invalid | +| INVALID_TOKEN_BURN_METADATA | 249 | The requested token burn metadata was invalid | +| CURRENT_TREASURY_STILL_OWNS_NFTS | 250 | The treasury for a unique token cannot be changed until it owns no NFTs | +| ACCOUNT_STILL_OWNS_NFTS | 251 | An account cannot be dissociated from a unique token if it owns NFTs for the token | +| TREASURY_MUST_OWN_BURNED_NFT | 252 | A NFT can only be burned when owned by the unique token's treasury | +| ACCOUNT_DOES_NOT_OWN_WIPED_NFT | 253 | An account did not own the NFT to be wiped | +| ACCOUNT_AMOUNT_TRANSFERS_ONLY_ALLOWED_FOR_FUNGIBLE_COMMON | 254 | An AccountAmount token transfers list referenced a token type other than FUNGIBLE_COMMON | +| MAX_NFTS_IN_PRICE_REGIME_HAVE_BEEN_MINTED | 255 | All the NFTs allowed in the current price regime have already been minted | +| PAYER_ACCOUNT_DELETED | 256 | The payer account has been marked as deleted | +| CUSTOM_FEE_CHARGING_EXCEEDED_MAX_RECURSION_DEPTH | 257 | The reference chain of custom fees for a transferred token exceeded the maximum length of 2 | +| CUSTOM_FEE_CHARGING_EXCEEDED_MAX_ACCOUNT_AMOUNTS | 258 | More than 20 balance adjustments were to satisfy a CryptoTransfer and its implied custom fee payments | +| INSUFFICIENT_SENDER_ACCOUNT_BALANCE_FOR_CUSTOM_FEE | 259 | The sender account in the token transfer transaction could not afford a custom fee | +| SERIAL_NUMBER_LIMIT_REACHED | 260 | Currently no more than 4,294,967,295 NFTs may be minted for a given unique token type | +| CUSTOM_ROYALTY_FEE_ONLY_ALLOWED_FOR_NON_FUNGIBLE_UNIQUE | 261 | Only tokens of type NON_FUNGIBLE_UNIQUE can have royalty fees | +| NO_REMAINING_AUTOMATIC_ASSOCIATIONS | 262 | The account has reached the limit on the automatic associations count. | +| EXISTING_AUTOMATIC_ASSOCIATIONS_EXCEED_GIVEN_LIMIT | 263 | Already existing automatic associations are more than the new maximum automatic associations. | +| REQUESTED_NUM_AUTOMATIC_ASSOCIATIONS_EXCEEDS_ASSOCIATION_LIMIT | 264 | Cannot set the number of automatic associations for an account more than the maximum allowed token associations tokens.maxPerAccount. | +| TOKEN_IS_PAUSED | 265 | Token is paused. This Token cannot be a part of any kind of Transaction until unpaused. | +| TOKEN_HAS_NO_PAUSE_KEY | 266 | Pause key is not set on token | +| INVALID_PAUSE_KEY | 267 | The provided pause key was invalid | +| FREEZE_UPDATE_FILE_DOES_NOT_EXIST | 268 | The update file in a freeze transaction body must exist. | +| FREEZE_UPDATE_FILE_HASH_DOES_NOT_MATCH | 269 | The hash of the update file in a freeze transaction body must match the in-memory hash. | +| NO_UPGRADE_HAS_BEEN_PREPARED | 270 | A FREEZE_UPGRADE transaction was handled with no previous update prepared. | +| NO_FREEZE_IS_SCHEDULED | 271 | A FREEZE_ABORT transaction was handled with no scheduled freeze. | +| UPDATE_FILE_HASH_CHANGED_SINCE_PREPARE_UPGRADE | 272 | The update file hash when handling a FREEZE_UPGRADE transaction differs from the file hash at the time of handling the PREPARE_UPGRADE transaction. | +| FREEZE_START_TIME_MUST_BE_FUTURE | 273 | The given freeze start time was in the (consensus) past. | +| PREPARED_UPDATE_FILE_IS_IMMUTABLE | 274 | The prepared update file cannot be updated or appended until either the upgrade has been completed, or a FREEZE_ABORT has been handled. | +| FREEZE_ALREADY_SCHEDULED | 275 | Once a freeze is scheduled, it must be aborted before any other type of freeze can can be performed. | +| FREEZE_UPGRADE_IN_PROGRESS | 276 | If an NMT upgrade has been prepared, the following operation must be a FREEZE_UPGRADE. (To issue a FREEZE_ONLY, submit a FREEZE_ABORT first.) | +| UPDATE_FILE_ID_DOES_NOT_MATCH_PREPARED | 277 | If an NMT upgrade has been prepared, the subsequent FREEZE_UPGRADE transaction must confirm the id of the file to be used in the upgrade. | +| UPDATE_FILE_HASH_DOES_NOT_MATCH_PREPARED | 278 | If an NMT upgrade has been prepared, the subsequent FREEZE_UPGRADE transaction must confirm the hash of the file to be used in the upgrade. | +| CONSENSUS_GAS_EXHAUSTED | 279 | Consensus throttle did not allow execution of this transaction. System is throttled at consensus level. | +| REVERTED_SUCCESS | 280 | A precompiled contract succeeded, but was later reverted. | +| MAX_STORAGE_IN_PRICE_REGIME_HAS_BEEN_USED | 281 | All contract storage allocated to the current price regime has been consumed. | +| INVALID_ALIAS_KEY | 282 | An alias used in a CryptoTransfer transaction is not the serialization of a primitive Key message--that is, a Key with a single Ed25519 or ECDSA(secp256k1) public key and no unknown protobuf fields. | +| UNEXPECTED_TOKEN_DECIMALS | 283 | A fungible token transfer expected a different number of decimals than the involved type actually has. | +| INVALID_PROXY_ACCOUNT_ID | 284 | The proxy account id is invalid or does not exist. | +| INVALID_TRANSFER_ACCOUNT_ID | 285 | The transfer account id in CryptoDelete transaction is invalid or does not exist. | +| INVALID_FEE_COLLECTOR_ACCOUNT_ID | 286 | The fee collector account id in TokenFeeScheduleUpdate is invalid or does not exist. | +| ALIAS_IS_IMMUTABLE | 287 | The alias already set on an account cannot be updated using CryptoUpdate transaction. | +| SPENDER_ACCOUNT_SAME_AS_OWNER | 288 | An approved allowance specifies a spender account that is the same as the hbar/token owner account. | +| AMOUNT_EXCEEDS_TOKEN_MAX_SUPPLY | 289 | The establishment or adjustment of an approved allowance cause the token allowance to exceed the token maximum supply. | +| NEGATIVE_ALLOWANCE_AMOUNT | 290 | The specified amount for an approved allowance cannot be negative. | +| CANNOT_APPROVE_FOR_ALL_FUNGIBLE_COMMON | 291 | The approveForAll flag cannot be set for a fungible token. | +| SPENDER_DOES_NOT_HAVE_ALLOWANCE | 292 | The spender does not have an existing approved allowance with the hbar/token owner. | +| AMOUNT_EXCEEDS_ALLOWANCE | 293 | The transfer amount exceeds the current approved allowance for the spender account. | +| MAX_ALLOWANCES_EXCEEDED | 294 | The payer account of an approveAllowances or adjustAllowance transaction is attempting to go beyond the maximum allowed number of allowances. | +| EMPTY_ALLOWANCES | 295 | No allowances have been specified in the approval transaction. | +| SPENDER_ACCOUNT_REPEATED_IN_ALLOWANCES | 296 | Spender is repeated more than once in Crypto or Token or NFT allowance lists in a single CryptoApproveAllowance transaction. | +| REPEATED_SERIAL_NUMS_IN_NFT_ALLOWANCES | 297 | Serial numbers are repeated in nft allowance for a single spender account | +| FUNGIBLE_TOKEN_IN_NFT_ALLOWANCES | 298 | Fungible common token used in NFT allowances | +| NFT_IN_FUNGIBLE_TOKEN_ALLOWANCES | 299 | Non fungible token used in fungible token allowances | +| INVALID_ALLOWANCE_OWNER_ID | 300 | The account id specified as the owner is invalid or does not exist. | +| INVALID_ALLOWANCE_SPENDER_ID | 301 | The account id specified as the spender is invalid or does not exist. | +| REPEATED_ALLOWANCES_TO_DELETE | 302 | [Deprecated] If the CryptoDeleteAllowance transaction has repeated crypto or token or Nft allowances to delete. | +| INVALID_DELEGATING_SPENDER | 303 | If the account Id specified as the delegating spender is invalid or does not exist. | +| DELEGATING_SPENDER_CANNOT_GRANT_APPROVE_FOR_ALL | 304 | The delegating Spender cannot grant approveForAll allowance on a NFT token type for another spender. | +| DELEGATING_SPENDER_DOES_NOT_HAVE_APPROVE_FOR_ALL | 305 | The delegating Spender cannot grant allowance on a NFT serial for another spender as it doesnt not have approveForAll granted on token-owner. | +| SCHEDULE_EXPIRATION_TIME_TOO_FAR_IN_FUTURE | 306 | The scheduled transaction could not be created because it's expiration_time was too far in the future. | +| SCHEDULE_EXPIRATION_TIME_MUST_BE_HIGHER_THAN_CONSENSUS_TIME | 307 | The scheduled transaction could not be created because it's expiration_time was less than or equal to the consensus time. | +| SCHEDULE_FUTURE_THROTTLE_EXCEEDED | 308 | The scheduled transaction could not be created because it would cause throttles to be violated on the specified expiration_time. | +| SCHEDULE_FUTURE_GAS_LIMIT_EXCEEDED | 309 | The scheduled transaction could not be created because it would cause the gas limit to be violated on the specified expiration_time. | +| INVALID_ETHEREUM_TRANSACTION | 310 | The ethereum transaction either failed parsing or failed signature validation, or some other EthereumTransaction error not covered by another response code. | +| WRONG_CHAIN_ID | 311 | EthereumTransaction was signed against a chainId that this network does not support. | +| WRONG_NONCE | 312 | This transaction specified an ethereumNonce that is not the current ethereumNonce of the account. | +| ACCESS_LIST_UNSUPPORTED | 313 | The ethereum transaction specified an access list, which the network does not support. | +| SCHEDULE_PENDING_EXPIRATION | 314 | A schedule being signed or deleted has passed it's expiration date and is pending execution if needed and then expiration. | +| CONTRACT_IS_TOKEN_TREASURY | 315 | A selfdestruct or ContractDelete targeted a contract that is a token treasury. | +| CONTRACT_HAS_NON_ZERO_TOKEN_BALANCES | 316 | A selfdestruct or ContractDelete targeted a contract with non-zero token balances. | +| CONTRACT_EXPIRED_AND_PENDING_REMOVAL | 317 | A contract referenced by a transaction is "detached"; that is, expired and lacking any hbar funds for auto-renewal payment---but still within its post-expiry grace period. | +| CONTRACT_HAS_NO_AUTO_RENEW_ACCOUNT | 318 | A ContractUpdate requested removal of a contract's auto-renew account, but that contract has no auto-renew account. | +| PERMANENT_REMOVAL_REQUIRES_SYSTEM_INITIATION | 319 | A delete transaction submitted via HAPI set permanent_removal=true | +| PROXY_ACCOUNT_ID_FIELD_IS_DEPRECATED | 320 | A CryptoCreate or ContractCreate used the deprecated proxyAccountID field. | +| SELF_STAKING_IS_NOT_ALLOWED | 321 | An account set the staked_account_id to itself in CryptoUpdate or ContractUpdate transactions. | +| INVALID_STAKING_ID | 322 | The staking account id or staking node id given is invalid or does not exist. | +| STAKING_NOT_ENABLED | 323 | Native staking, while implemented, has not yet enabled by the council. | +| INVALID_PRNG_RANGE | 324 | The range provided in UtilPrng transaction is negative. | +| MAX_ENTITIES_IN_PRICE_REGIME_HAVE_BEEN_CREATED | 325 | The maximum number of entities allowed in the current price regime have been created. | +| INVALID_FULL_PREFIX_SIGNATURE_FOR_PRECOMPILE | 326 | The full prefix signature for precompile is not valid | +| INSUFFICIENT_BALANCES_FOR_STORAGE_RENT | 327 | The combined balances of a contract and its auto-renew account (if any) did not cover the rent charged for net new storage used in a transaction. | +| MAX_CHILD_RECORDS_EXCEEDED | 328 | A contract transaction tried to use more than the allowed number of child records, via either system contract records or internal contract creations. | +| INSUFFICIENT_BALANCES_FOR_RENEWAL_FEES | 329 | The combined balances of a contract and its auto-renew account (if any) or balance of an account did not cover the auto-renewal fees in a transaction. | +| TRANSACTION_HAS_UNKNOWN_FIELDS | 330 | A transaction's protobuf message includes unknown fields; could mean that a client expects not-yet-released functionality to be available. | +| ACCOUNT_IS_IMMUTABLE | 331 | The account cannot be modified. Account's key is not set | +| ALIAS_ALREADY_ASSIGNED | 332 | An alias that is assigned to an account or contract cannot be assigned to another account or contract. | +| INVALID_METADATA_KEY | 333 | A provided metadata key was invalid. Verification includes, for example, checking the size of Ed25519 and ECDSA(secp256k1) public keys. | +| TOKEN_HAS_NO_METADATA_KEY | 334 | Metadata key is not set on token | +| MISSING_TOKEN_METADATA | 335 | Token Metadata is not provided | +| MISSING_SERIAL_NUMBERS | 336 | NFT serial numbers are missing in the TokenUpdateNftsTransactionBody | +| TOKEN_HAS_NO_ADMIN_KEY | 337 | Admin key is not set on token | +| NODE_DELETED | 338 | A transaction failed because the consensus node identified is deleted from the address book. | +| INVALID_NODE_ID | 339 | A transaction failed because the consensus node identified is not valid or does not exist in state. | +| INVALID_GOSSIP_ENDPOINT | 340 | A transaction failed because one or more entries in the list of service endpoints for the `gossip_endpoint` field is invalid.
The most common cause for this response is a service endpoint that has the domain name (DNS) set rather than address and port. | +| INVALID_NODE_ACCOUNT_ID | 341 | A transaction failed because the node account identifier provided does not exist or is not valid.
One common source of this error is providing a node account identifier using the "alias" form rather than "numeric" form. | +| INVALID_NODE_DESCRIPTION | 342 | A transaction failed because the description field cannot be encoded as UTF-8 or is more than 100 bytes when encoded. | +| INVALID_SERVICE_ENDPOINT | 343 | A transaction failed because one or more entries in the list of service endpoints for the `service_endpoint` field is invalid.
The most common cause for this response is a service endpoint that has the domain name (DNS) set rather than address and port. | +| INVALID_GOSSIP_CA_CERTIFICATE | 344 | A transaction failed because the TLS certificate provided for the node is missing or invalid.

Probable Causes

The certificate MUST be a TLS certificate of a type permitted for gossip signatures.
The value presented MUST be a UTF-8 NFKD encoding of the TLS certificate.
The certificate encoded MUST be in PEM format.
The `gossip_ca_certificate` field is REQUIRED and MUST NOT be empty. | +| INVALID_GRPC_CERTIFICATE | 345 | A transaction failed because the hash provided for the gRPC certificate is present but invalid.

Probable Causes

The `grpc_certificate_hash` MUST be a SHA-384 hash.
The input hashed MUST be a UTF-8 NFKD encoding of the actual TLS certificate.
The certificate to be encoded MUST be in PEM format. | +| INVALID_MAX_AUTO_ASSOCIATIONS | 346 | The maximum automatic associations value is not valid.
The most common cause for this error is a value less than `-1`. | +| MAX_NODES_CREATED | 347 | The maximum number of nodes allowed in the address book have been created. | +| IP_FQDN_CANNOT_BE_SET_FOR_SAME_ENDPOINT | 348 | In ServiceEndpoint, domain_name and ipAddressV4 are mutually exclusive | +| GOSSIP_ENDPOINT_CANNOT_HAVE_FQDN | 349 | Fully qualified domain name is not allowed in gossip_endpoint | +| FQDN_SIZE_TOO_LARGE | 350 | In ServiceEndpoint, domain_name size too large | +| INVALID_ENDPOINT | 351 | ServiceEndpoint is invalid | +| GOSSIP_ENDPOINTS_EXCEEDED_LIMIT | 352 | The number of gossip endpoints exceeds the limit | +| TOKEN_REFERENCE_REPEATED | 353 | The transaction attempted to use duplicate `TokenReference`.
This affects `TokenReject` attempting to reject same token reference more than once. | +| INVALID_OWNER_ID | 354 | The account id specified as the owner in `TokenReject` is invalid or does not exist. | +| TOKEN_REFERENCE_LIST_SIZE_LIMIT_EXCEEDED | 355 | The transaction attempted to use more than the allowed number of `TokenReference`. | +| SERVICE_ENDPOINTS_EXCEEDED_LIMIT | 356 | The number of service endpoints exceeds the limit | +| INVALID_IPV4_ADDRESS | 357 | The IPv4 address is invalid | +| EMPTY_TOKEN_REFERENCE_LIST | 358 | The transaction attempted to use empty `TokenReference` list. | +| UPDATE_NODE_ACCOUNT_NOT_ALLOWED | 359 | The node account is not allowed to be updated | +| TOKEN_HAS_NO_METADATA_OR_SUPPLY_KEY | 360 | The token has no metadata or supply key | +| EMPTY_PENDING_AIRDROP_ID_LIST | 361 | The list of `PendingAirdropId`s is empty and MUST NOT be empty. | +| PENDING_AIRDROP_ID_REPEATED | 362 | A `PendingAirdropId` is repeated in a `claim` or `cancel` transaction. | +| PENDING_AIRDROP_ID_LIST_TOO_LONG | 363 | The number of `PendingAirdropId` values in the list exceeds the maximum allowable number. | +| PENDING_NFT_AIRDROP_ALREADY_EXISTS | 364 | A pending airdrop already exists for the specified NFT. | +| ACCOUNT_HAS_PENDING_AIRDROPS | 365 | The identified account is sender for one or more pending airdrop(s) and cannot be deleted.

The requester SHOULD cancel all pending airdrops before resending this transaction. | +| THROTTLED_AT_CONSENSUS | 366 | Consensus throttle did not allow execution of this transaction.
The transaction should be retried after a modest delay. | +| INVALID_PENDING_AIRDROP_ID | 367 | The provided pending airdrop id is invalid.
This pending airdrop MAY already be claimed or cancelled.

The client SHOULD query a mirror node to determine the current status of the pending airdrop. | +| TOKEN_AIRDROP_WITH_FALLBACK_ROYALTY | 368 | The token to be airdropped has a fallback royalty fee and cannot be sent or claimed via an airdrop transaction. | +| INVALID_TOKEN_IN_PENDING_AIRDROP | 369 | This airdrop claim is for a pending airdrop with an invalid token.
The token might be deleted, or the sender may not have enough tokens to fulfill the offer.

The client SHOULD query mirror node to determine the status of the pending airdrop and whether the sender can fulfill the offer. | + + + + + + + + + + diff --git a/documents/api/services/response_header.md b/documents/api/services/response_header.md new file mode 100644 index 00000000..bb788ca0 --- /dev/null +++ b/documents/api/services/response_header.md @@ -0,0 +1,58 @@ +## Table of Contents + +- [response_header.proto](#response_header-proto) + - [ResponseHeader](#proto-ResponseHeader) + + + + + +

Top

+ +## response_header.proto +# Response Header +A standard header for all query responses. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ResponseHeader +A standard header returned with every query response. + +The fields for `cost` or `stateProof` MAY be unset if the requested +`ResponseType` does not request those values.
+The `responseType` SHALL match the request response type.
+The `nodeTransactionPrecheckCode` field SHALL contain the result code +for the query. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| nodeTransactionPrecheckCode | [ResponseCodeEnum](#proto-ResponseCodeEnum) | | The result code for this query.

This value SHALL indicate either success or the reason for failure. | +| responseType | [ResponseType](#proto-ResponseType) | | The response type requested for this query.

This SHALL be the response type requested in the query header. | +| cost | [uint64](#uint64) | | Requested cost estimate.
This is the fee that _would be_ charged if the query was executed.

This value SHALL be set if the response type requested requires cost information, and SHALL NOT be set otherwise.
This value SHALL include the query fee, but SHALL NOT include the transfer fee required to execute the fee payment transaction. | +| stateProof | [bytes](#bytes) | | A state proof for the information requested. + +This field SHALL NOT be set if the response type does not require a state proof.
This field SHALL NOT be set if a state proof is not available for the query type.
This field SHALL be set if the response type requested a state proof and a state proof is available. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/schedulable_transaction_body.md b/documents/api/services/schedulable_transaction_body.md new file mode 100644 index 00000000..2146219e --- /dev/null +++ b/documents/api/services/schedulable_transaction_body.md @@ -0,0 +1,102 @@ +## Table of Contents + +- [schedulable_transaction_body.proto](#schedulable_transaction_body-proto) + - [SchedulableTransactionBody](#proto-SchedulableTransactionBody) + + + + + +

Top

+ +## schedulable_transaction_body.proto +# Schedulable Transaction Body +A message that replicates the `TransactionBody` message, with slight +changes to exclude fields that cannot be scheduled via a `scheduleCreate` +transaction. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### SchedulableTransactionBody +A schedulable transaction. + +The network configuration `scheduling.whitelist` limits which of these +transaction types may actually be scheduled. As of version `0.50.0` of the +consensus node software this list contains only `CryptoTransfer`, +`ConsensusSubmitMessage`, `TokenBurn`, `TokenMint`, +and `CryptoApproveAllowance`. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| transactionFee | [uint64](#uint64) | | A limit for the transaction fee the client is willing to pay.

The network SHALL NOT charge fees greater than this value. | +| memo | [string](#string) | | A short description of the schedulable transaction.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8. | +| consensusCreateTopic | [ConsensusCreateTopicTransactionBody](#proto-ConsensusCreateTopicTransactionBody) | | Create a topic. | +| consensusUpdateTopic | [ConsensusUpdateTopicTransactionBody](#proto-ConsensusUpdateTopicTransactionBody) | | Update a topic. | +| consensusDeleteTopic | [ConsensusDeleteTopicTransactionBody](#proto-ConsensusDeleteTopicTransactionBody) | | Delete a topic. | +| consensusSubmitMessage | [ConsensusSubmitMessageTransactionBody](#proto-ConsensusSubmitMessageTransactionBody) | | Submit a message to a topic.
A message may be "chunked", and submitted in parts, if the total message size exceeds the limit for a single transaction. | +| contractCall | [ContractCallTransactionBody](#proto-ContractCallTransactionBody) | | Call a function defined on a smart contract. | +| contractCreateInstance | [ContractCreateTransactionBody](#proto-ContractCreateTransactionBody) | | Create a smart contract. | +| contractUpdateInstance | [ContractUpdateTransactionBody](#proto-ContractUpdateTransactionBody) | | Update a smart contract. | +| contractDeleteInstance | [ContractDeleteTransactionBody](#proto-ContractDeleteTransactionBody) | | Delete a smart contract and transfer remaining balance to a specified account. | +| cryptoApproveAllowance | [CryptoApproveAllowanceTransactionBody](#proto-CryptoApproveAllowanceTransactionBody) | | Add one or more approved allowances for spenders to transfer the paying account's hbar or tokens. | +| cryptoDeleteAllowance | [CryptoDeleteAllowanceTransactionBody](#proto-CryptoDeleteAllowanceTransactionBody) | | Delete one or more approvals for spenders to transfer the paying account's hbar or tokens. | +| cryptoCreateAccount | [CryptoCreateTransactionBody](#proto-CryptoCreateTransactionBody) | | Create a new Hedera account. | +| cryptoDelete | [CryptoDeleteTransactionBody](#proto-CryptoDeleteTransactionBody) | | Delete an Hedera account.
This will mark the account as deleted, and transfer all remaining HBAR to a receiver account. | +| cryptoTransfer | [CryptoTransferTransactionBody](#proto-CryptoTransferTransactionBody) | | Transfer HBAR between accounts. | +| cryptoUpdateAccount | [CryptoUpdateTransactionBody](#proto-CryptoUpdateTransactionBody) | | Modify an Hedera account. | +| fileAppend | [FileAppendTransactionBody](#proto-FileAppendTransactionBody) | | Append data to the end of a file. | +| fileCreate | [FileCreateTransactionBody](#proto-FileCreateTransactionBody) | | Create a new file. | +| fileDelete | [FileDeleteTransactionBody](#proto-FileDeleteTransactionBody) | | Delete a file.
This will remove the content of the file, and mark the file as deleted. | +| fileUpdate | [FileUpdateTransactionBody](#proto-FileUpdateTransactionBody) | | Modify a file.
This may modify any metadata, and/or _replace_ the content. | +| systemDelete | [SystemDeleteTransactionBody](#proto-SystemDeleteTransactionBody) | | Delete a file as an Hedera administrative function.
This is a privileged operation. | +| systemUndelete | [SystemUndeleteTransactionBody](#proto-SystemUndeleteTransactionBody) | | Restore a file deleted via `systemDelete`.
This is a privileged operation. | +| freeze | [FreezeTransactionBody](#proto-FreezeTransactionBody) | | Freeze the network.
This is actually several possible operations, and the caller should examine the "freeze service" for more detail.
This is a privileged operation. | +| util_prng | [UtilPrngTransactionBody](#proto-UtilPrngTransactionBody) | | Provide a deterministic pseudorandom number based on network state. | +| nodeCreate | [com.hedera.hapi.node.addressbook.NodeCreateTransactionBody](#com-hedera-hapi-node-addressbook-NodeCreateTransactionBody) | | Create a new node in the network address book.
This is a privileged operation. | +| nodeUpdate | [com.hedera.hapi.node.addressbook.NodeUpdateTransactionBody](#com-hedera-hapi-node-addressbook-NodeUpdateTransactionBody) | | Update a node in the network address book.
This is a privileged operation. | +| nodeDelete | [com.hedera.hapi.node.addressbook.NodeDeleteTransactionBody](#com-hedera-hapi-node-addressbook-NodeDeleteTransactionBody) | | Delete a node from the network address book.
This will mark the node as deleted.
This is a privileged operation. | +| scheduleDelete | [ScheduleDeleteTransactionBody](#proto-ScheduleDeleteTransactionBody) | | Delete a schedule.
The schedule will be marked as deleted. | +| tokenCreation | [TokenCreateTransactionBody](#proto-TokenCreateTransactionBody) | | Create a new Hedera token. | +| tokenFreeze | [TokenFreezeAccountTransactionBody](#proto-TokenFreezeAccountTransactionBody) | | Freeze an account with respect to a token.
A frozen account cannot transact in that token until unfrozen. | +| tokenUnfreeze | [TokenUnfreezeAccountTransactionBody](#proto-TokenUnfreezeAccountTransactionBody) | | Unfreeze an account with respect to a token. | +| tokenGrantKyc | [TokenGrantKycTransactionBody](#proto-TokenGrantKycTransactionBody) | | Grant KYC to an account with respect to a token.
KYC is generally a "know your customer" assertion that a responsible entity has sufficient information to positively identify the account holder to relevant authorities. | +| tokenRevokeKyc | [TokenRevokeKycTransactionBody](#proto-TokenRevokeKycTransactionBody) | | Revoke KYC from an account with respect to a token. | +| tokenDeletion | [TokenDeleteTransactionBody](#proto-TokenDeleteTransactionBody) | | Deletes an Hedera token.
The token will be marked deleted. | +| tokenUpdate | [TokenUpdateTransactionBody](#proto-TokenUpdateTransactionBody) | | Update an Hedera token.
Depending on what fields are to be modified, the signature requirements will vary. See `TokenUpdateTransactionBody` for further detail. | +| token_update_nfts | [TokenUpdateNftsTransactionBody](#proto-TokenUpdateNftsTransactionBody) | | Update one or more non-fungible/unique tokens.
This will update metadata for one or more serial numbers within a collection (token type). | +| tokenMint | [TokenMintTransactionBody](#proto-TokenMintTransactionBody) | | Mint new tokens.
All minted tokens will be delivered to the treasury account for the token type. The "mint key" for the token must sign this transaction. | +| tokenBurn | [TokenBurnTransactionBody](#proto-TokenBurnTransactionBody) | | Burn tokens from the treasury account.
The "burn key" for the token must sign this transaction. | +| tokenWipe | [TokenWipeAccountTransactionBody](#proto-TokenWipeAccountTransactionBody) | | Wipe tokens from an account.
This will remove a specified amount of fungible/common tokens or a specified list of non-fungible/unique serial numbered tokens of a given token type from an Hedera account. The removed tokens are _burned_ as if by a `tokenBurn` transaction.
The "wipe key" for the token must sign this transaction. | +| tokenAssociate | [TokenAssociateTransactionBody](#proto-TokenAssociateTransactionBody) | | Associate tokens to an account. | +| tokenDissociate | [TokenDissociateTransactionBody](#proto-TokenDissociateTransactionBody) | | Dissociate tokens from an account. | +| token_fee_schedule_update | [TokenFeeScheduleUpdateTransactionBody](#proto-TokenFeeScheduleUpdateTransactionBody) | | Update the custom fee schedule for a token.
This transaction must be signed by the "fee schedule key" for the token. | +| token_pause | [TokenPauseTransactionBody](#proto-TokenPauseTransactionBody) | | Pause a Token.
This transaction must be signed by the "pause key" for the token. | +| token_unpause | [TokenUnpauseTransactionBody](#proto-TokenUnpauseTransactionBody) | | Unpause a Token.
This transaction must be signed by the "pause key" for the token. | +| tokenReject | [TokenRejectTransactionBody](#proto-TokenRejectTransactionBody) | | "Reject" undesired tokens.
This transaction will transfer one or more tokens or token balances held by the requesting account to the treasury for each token type.

Each transfer MUST be one of the following:

When complete, the requesting account SHALL NOT hold the rejected tokens.
Custom fees and royalties defined for the tokens rejected SHALL NOT be charged for this transaction. | +| tokenCancelAirdrop | [TokenCancelAirdropTransactionBody](#proto-TokenCancelAirdropTransactionBody) | | Cancel an "airdrop".
This transaction cancels a pending airdrop for one or more recipients.

The airdrop(s) to cancel MUST be pending, and not claimed.
| +| tokenClaimAirdrop | [TokenClaimAirdropTransactionBody](#proto-TokenClaimAirdropTransactionBody) | | Claim an "airdrop". This transaction "claims" one or more pending "airdrops".

The airdrop(s) to claim MUST be pending, and not already claimed.
| +| tokenAirdrop | [TokenAirdropTransactionBody](#proto-TokenAirdropTransactionBody) | | Send an "airdrop" of tokens to one or more recipients.

This transaction unilaterally "gifts" tokens by transferring them from a "sender" account to the "recipient" account(s). If any recipient is not already associated to the token to airdrop, or has set a "reciever signature required" flag, then that recipient is recorded as a "pending" airdrop which must be "claimed". All other recipients receive the "airdropped" tokens immediately. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/schedule_create.md b/documents/api/services/schedule_create.md new file mode 100644 index 00000000..64949628 --- /dev/null +++ b/documents/api/services/schedule_create.md @@ -0,0 +1,126 @@ +## Table of Contents + +- [schedule_create.proto](#schedule_create-proto) + - [ScheduleCreateTransactionBody](#proto-ScheduleCreateTransactionBody) + + + + + +

Top

+ +## schedule_create.proto +# Schedule Create +Message to create a schedule, which is an instruction to execute some other +transaction (the scheduled transaction) at a future time, either when +enough signatures are gathered (short term) or when the schedule expires +(long term). In all cases the scheduled transaction is not executed if +signature requirements are not met before the schedule expires. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ScheduleCreateTransactionBody +Create a new Schedule. + +#### Requirements +This transaction SHALL create a new _schedule_ entity in network state.
+The schedule created SHALL contain the `scheduledTransactionBody` to be +executed.
+If successful the receipt SHALL contain a `scheduleID` with the full +identifier of the schedule created.
+When a schedule _executes_ successfully, the receipt SHALL include a +`scheduledTransactionID` with the `TransactionID` of the transaction that +executed.
+When a scheduled transaction is executed the network SHALL charge the +regular _service_ fee for the transaction to the `payerAccountID` for +that schedule, but SHALL NOT charge node or network fees.
+If the `payerAccountID` field is not set, the effective `payerAccountID` +SHALL be the `payer` for this create transaction.
+If an `adminKey` is not specified, or is an empty `KeyList`, the schedule +created SHALL be immutable.
+An immutable schedule MAY be signed, and MAY execute, but SHALL NOT be +deleted.
+If two schedules have the same values for all fields except `payerAccountID` +then those two schedules SHALL be deemed "identical".
+If a `scheduleCreate` requests a new schedule that is identical to an +existing schedule, the transaction SHALL fail and SHALL return a status +code of `IDENTICAL_SCHEDULE_ALREADY_CREATED` in the receipt.
+The receipt for a duplicate schedule SHALL include the `ScheduleID` of the +existing schedule and the `TransactionID` of the earlier `scheduleCreate` +so that the earlier schedule may be queried and/or referred to in a +subsequent `scheduleSign`. + +#### Signature Requirements +A `scheduleSign` transaction SHALL be used to add additional signatures +to an existing schedule.
+Each signature SHALL "activate" the corresponding cryptographic("primitive") +key for that schedule.
+Signature requirements SHALL be met when the set of active keys includes +all keys required by the scheduled transaction.
+A scheduled transaction for a "long term" schedule SHALL NOT execute if +the signature requirements for that transaction are not met when the +network consensus time reaches the schedule `expiration_time`.
+A "short term" schedule SHALL execute immediately once signature +requirements are met. This MAY be immediately when created. + +#### Long Term Schedules +A "short term" schedule SHALL have the flag `wait_for_expiry` _unset_.
+A "long term" schedule SHALL have the flag `wait_for_expiry` _set_.
+A "long term" schedule SHALL NOT be accepted if the network configuration +`scheduling.longTermEnabled` is not enabled.
+A "long term" schedule SHALL execute when the current consensus time +matches or exceeds the `expiration_time` for that schedule, if the +signature requirements for the scheduled transaction +are met at that instant.
+A "long term" schedule SHALL NOT execute before the current consensus time +matches or exceeds the `expiration_time` for that schedule.
+A "long term" schedule SHALL expire, and be removed from state, after the +network consensus time exceeds the schedule `expiration_time`.
+A short term schedule SHALL expire, and be removed from state, +after the network consensus time exceeds the current network +configuration for `ledger.scheduleTxExpiryTimeSecs`. + +> Note +>> Long term schedules are not (as of release 0.50.0) enabled. Any schedule +>> created currently MUST NOT set the `wait_for_expiry` flag.
+>> When long term schedules are not enabled, schedules SHALL NOT be +>> executed at expiration, and MUST meet signature requirements strictly +>> before expiration to be executed. + +### Record Stream Effects +If the scheduled transaction is executed immediately, the transaction +record SHALL include a `scheduleRef` with the schedule identifier of the +schedule created. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| scheduledTransactionBody | [SchedulableTransactionBody](#proto-SchedulableTransactionBody) | | A scheduled transaction.

This value is REQUIRED.
This transaction body MUST be one of the types enabled in the network configuration value `scheduling.whitelist`. | +| memo | [string](#string) | | A short description of the schedule.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8. | +| adminKey | [Key](#proto-Key) | | A `Key` required to delete this schedule.

If this is not set, or is an empty `KeyList`, this schedule SHALL be immutable and SHALL NOT be deleted. | +| payerAccountID | [AccountID](#proto-AccountID) | | An account identifier of a `payer` for the scheduled transaction.

This value MAY be unset. If unset, the `payer` for this `scheduleCreate` transaction SHALL be the `payer` for the scheduled transaction.
If this is set, the identified account SHALL be charged the fees required for the scheduled transaction when it is executed.
If the actual `payer` for the _scheduled_ transaction lacks sufficient HBAR balance to pay service fees for the scheduled transaction _when it executes_, the scheduled transaction SHALL fail with `INSUFFICIENT_PAYER_BALANCE`.
| +| expiration_time | [Timestamp](#proto-Timestamp) | | An expiration time.

If not set, the expiration SHALL default to the current consensus time advanced by either the network configuration value `scheduling.maxExpirationFutureSeconds`, if `wait_for_expiry` is set and "long term" schedules are enabled, or the network configuration value `ledger.scheduleTxExpiryTimeSecs` otherwise. | +| wait_for_expiry | [bool](#bool) | | A flag to delay execution until expiration.

If this flag is set the scheduled transaction SHALL NOT be evaluated for execution before the network consensus time matches or exceeds the `expiration_time`.
If this flag is not set, the scheduled transaction SHALL be executed immediately when all required signatures are received, whether in this `scheduleCreate` transaction or a later `scheduleSign` transaction.
This value SHALL NOT be used and MUST NOT be set when the network configuration value `scheduling.longTermEnabled` is not enabled. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/schedule_delete.md b/documents/api/services/schedule_delete.md new file mode 100644 index 00000000..1feb704e --- /dev/null +++ b/documents/api/services/schedule_delete.md @@ -0,0 +1,55 @@ +## Table of Contents + +- [schedule_delete.proto](#schedule_delete-proto) + - [ScheduleDeleteTransactionBody](#proto-ScheduleDeleteTransactionBody) + + + + + +

Top

+ +## schedule_delete.proto +# Schedule Delete +A transaction body for a `scheduleDelete` transaction. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ScheduleDeleteTransactionBody +Mark a schedule in the network state as deleted. + +This transaction MUST be signed by the `adminKey` for the +identified schedule.
+If a schedule does not have `adminKey` set or if `adminKey` is an empty +`KeyList`, that schedule SHALL be immutable and MUST NOT be deleted.
+A deleted schedule SHALL not be executed.
+A deleted schedule MUST NOT be the subject of a subsequent +`scheduleSign` transaction.
+ + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| scheduleID | [ScheduleID](#proto-ScheduleID) | | A schedule identifier.

This MUST identify the schedule which SHALL be deleted. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/schedule_get_info.md b/documents/api/services/schedule_get_info.md new file mode 100644 index 00000000..4f78c4a6 --- /dev/null +++ b/documents/api/services/schedule_get_info.md @@ -0,0 +1,97 @@ +## Table of Contents + +- [schedule_get_info.proto](#schedule_get_info-proto) + - [ScheduleGetInfoQuery](#proto-ScheduleGetInfoQuery) + - [ScheduleGetInfoResponse](#proto-ScheduleGetInfoResponse) + - [ScheduleInfo](#proto-ScheduleInfo) + + + + + +

Top

+ +## schedule_get_info.proto +# Schedule Get Information +Query body and response to retrieve information about a scheduled +transaction. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ScheduleGetInfoQuery +Request for information about a scheduled transaction. + +If the requested schedule does not exist, the network SHALL respond +with `INVALID_SCHEDULE_ID`. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.
This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither). | +| scheduleID | [ScheduleID](#proto-ScheduleID) | | A schedule identifier.

This SHALL identify the schedule to retrieve.
This field is REQUIRED. | + + + + + + + + +### ScheduleGetInfoResponse +A response message for a `getScheduleInfo` query. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| scheduleInfo | [ScheduleInfo](#proto-ScheduleInfo) | | Detail information for a schedule.

This field SHALL contain all available schedule detail. | + + + + + + + + +### ScheduleInfo +Information summarizing schedule state + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| scheduleID | [ScheduleID](#proto-ScheduleID) | | A schedule identifier.

This SHALL identify the schedule retrieved. | +| deletion_time | [Timestamp](#proto-Timestamp) | | A deletion timestamp.

If the schedule was deleted, this SHALL be set to the consensus timestamp of the `deleteSchedule` transaction.
If the schedule is _not_ deleted, this field SHALL NOT be set. | +| execution_time | [Timestamp](#proto-Timestamp) | | An execution timestamp.

If the schedule was completed, and the _scheduled_ transaction executed, this SHALL be set to the consensus timestamp of the transaction that initiated that execution.
If the schedule is _not_ complete, this field SHALL NOT be set. | +| expirationTime | [Timestamp](#proto-Timestamp) | | An expiration timestamp.
This represents the time at which the schedule will expire. For a long-term schedule (if enabled) this is when the schedule will be executed, assuming it meets signature requirements at that time. For a short-term schedule, this is the deadline to complete the signature requirements for the scheduled transaction to execute. Regardless of schedule type, the schedule will be removed from state when it expires.

A schedule SHALL be removed from state when it expires.
A short-term schedule MUST meet signature requirements strictly before expiration or it SHALL NOT be executed.
A long-term schedule SHALL be executed if, and only if, all signature requirements for the scheduled transaction are met at expiration.
A long-term schedule SHALL NOT be executed if any signature requirement for the scheduled transaction are not met at expiration.
| +| scheduledTransactionBody | [SchedulableTransactionBody](#proto-SchedulableTransactionBody) | | A scheduled transaction.

This SHALL be a transaction type enabled in the network property `scheduling.whitelist`, and SHALL NOT be any other transaction type.
This transaction SHALL be executed if the schedule meets all signature and execution time requirements for this transaction.
The signature requirements for this transaction SHALL be evaluated at schedule creation, SHALL be reevaluated with each `signSchedule` transaction, and, for long-term schedules, SHALL be reevaluated when the schedule expires.
| +| memo | [string](#string) | | A short description for this schedule.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8. | +| adminKey | [Key](#proto-Key) | | The key used to delete the schedule from state | +| signers | [KeyList](#proto-KeyList) | | A list of "valid" signatures for this schedule.
This list contains only "primitive" (i.e. cryptographic or contract) signatures. The full signature requirements for the scheduled transaction are evaluated as if this list of keys had signed the scheduled transaction directly.

This list SHALL contain every "primitive" key that has signed the original `createSchedule`, or any subsequent `signSchedule` transaction.
This list MAY elide any signature not likely to be required by the scheduled transaction. Such requirement SHOULD be evaluated when the signature is presented (i.e. during evaluation of a `createSchedule` or `signSchedule` transaction). | +| creatorAccountID | [AccountID](#proto-AccountID) | | An account identifier.

This SHALL identify the account that created this schedule. | +| payerAccountID | [AccountID](#proto-AccountID) | | An account identifier.

The identified account SHALL pay the full transaction fee for the scheduled transaction _when it executes_. | +| scheduledTransactionID | [TransactionID](#proto-TransactionID) | | A transaction identifier.

This SHALL be recorded as the transaction identifier for the _scheduled_ transaction, if (and when) it is executed. | +| ledger_id | [bytes](#bytes) | | The ledger ID of the network that generated this response.
This is originally defined in `HIP-198` and depends on network configuration.
The current values, as of Q1 2024, are

Mainnet
0x00
Testnet
0x01
Previewnet
0x02
Undefined
0x03
Reserved
0x04
| +| wait_for_expiry | [bool](#bool) | | A flag indicating this schedule will execute when it expires.

If this field is set

If this field is not set | + + + + + + + + + + + + + + + diff --git a/documents/api/services/schedule_service.md b/documents/api/services/schedule_service.md new file mode 100644 index 00000000..09a17423 --- /dev/null +++ b/documents/api/services/schedule_service.md @@ -0,0 +1,91 @@ +## Table of Contents + +- [schedule_service.proto](#schedule_service-proto) + - [ScheduleService](#proto-ScheduleService) + + + + + +

Top

+ +## schedule_service.proto +# Schedule Service +gRPC service definitions for the Schedule Service. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + + + + + + + +### ScheduleService +Transactions and queries for the Schedule Service.
+The Schedule Service enables transactions to be submitted without all +required signatures and offers a `scheduleSign` transaction to provide +additional signatures independently after the schedule is created. The +scheduled transaction may be executed immediately when all required +signatures are present, or at expiration if "long term" schedules +are enabled in network configuration. + +### Execution +Scheduled transactions SHALL be executed under the following conditions. +1. If "long term" schedules are enabled and `wait_for_expiry` is set for + that schedule then the transaction SHALL NOT be executed before the + network consensus time matches or exceeds the `expiration_time` field + for that schedule. +1. If "long term" schedules are enabled and `wait_for_expiry` is _not_ set + for that schedule, then the transaction SHALL be executed when all + signatures required by the scheduled transaction are active for that + schedule. This MAY be immediately after the `scheduleCreate` or a + subsequent `scheduleSign` transaction, or MAY be at expiration if + the signature requirements are met at that time. +1. If "long term" schedules are _disabled_, then the scheduled transaction + SHALL be executed immediately after all signature requirements for the + scheduled transaction are met during the `scheduleCreate` or a subsequent + `scheduleSign` transaction. The scheduled transaction SHALL NOT be + on expiration when "long term" schedules are disabled. + +A schedule SHALL remain in state and MAY be queried with a `getScheduleInfo` +transaction after execution, until the schedule expires.
+When network consensus time matches or exceeds the `expiration_time` for +a schedule, that schedule SHALL be removed from state, whether it has +executed or not.
+If "long term" schedules are _disabled_, the maximum expiration time SHALL +be the consensus time of the `scheduleCreate` transaction extended by +the network configuration value `ledger.scheduleTxExpiryTimeSecs`. + +### Record Stream Effects +When a scheduled transaction is executed, the timestamp in the transaction +identifier for that transaction SHALL be 1 nanosecond after the consensus +timestamp for the transaction that resulted in its execution. If execution +occurred at expiration, that transaction may be almost any transaction, +including another scheduled transaction that executed at expiration.
+The transaction identifier for a scheduled transaction that is executed +SHALL have the `scheduled` flag set and SHALL inherit the `accountID` and +`transactionValidStart` values from the `scheduleCreate` that created the +schedule.
+The `scheduleRef` property of the record for a scheduled transaction SHALL +be populated with the schedule identifier of the schedule that executed. + +| Method Name | Request Type | Response Type | Description | +| ----------- | ------------ | ------------- | ------------| +| createSchedule | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Create a new Schedule.

If all signature requirements are met with this transaction, the scheduled transaction MAY execute immediately. | +| signSchedule | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Add signatures to an existing schedule.

Signatures on this transaction SHALL be added to the set of active signatures on the schedule, and MAY result in execution of the scheduled transaction if all signature requirements are met. | +| deleteSchedule | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Mark an existing schedule deleted.

Once deleted a schedule SHALL NOT be executed and any subsequent `scheduleSign` transaction SHALL fail. | +| getScheduleInfo | [Query](#proto-Query) | [Response](#proto-Response) | Retrieve the metadata for a schedule. | + + + + + diff --git a/documents/api/services/schedule_sign.md b/documents/api/services/schedule_sign.md new file mode 100644 index 00000000..841ffafc --- /dev/null +++ b/documents/api/services/schedule_sign.md @@ -0,0 +1,71 @@ +## Table of Contents + +- [schedule_sign.proto](#schedule_sign-proto) + - [ScheduleSignTransactionBody](#proto-ScheduleSignTransactionBody) + + + + + +

Top

+ +## schedule_sign.proto +# Schedule Sign +Transaction body for a `scheduleSign` transaction to add signatures +to an existing scheduled transaction. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ScheduleSignTransactionBody +Add signatures to an existing scheduled transaction. + +When a schedule _executes_ successfully, the receipt SHALL include a +`scheduledTransactionID` with the `TransactionID` of the transaction that +executed.
+When a scheduled transaction is executed the network SHALL charge the +regular _service_ fee for the transaction to the `payerAccountID` for +that schedule, but SHALL NOT charge node or network fees.
+If the `payerAccountID` field is not set, the effective `payerAccountID` +SHALL be the `payer` for this create transaction.
+Each signature on this transaction SHALL "activate" the corresponding +cryptographic("primitive") key for the schedule identified.
+Signature requirements SHALL be met when the set of active keys includes +all keys required by the scheduled transaction.
+A scheduled transaction for a "long term" schedule SHALL NOT execute if +the signature requirements for that transaction are not met when the +network consensus time reaches the schedule `expiration_time`.
+A "short term" schedule SHALL execute immediately once signature +requirements are met. This MAY be immediately when created.
+ +### Record Stream Effects +If the scheduled transaction is executed immediately following this +`scheduleSign` transaction, the transaction record SHALL include a +`scheduleRef` with the schedule identifier `scheduleID`. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| scheduleID | [ScheduleID](#proto-ScheduleID) | | A schedule identifier.

This MUST identify the schedule to which signatures SHALL be added. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/smart_contract_service.md b/documents/api/services/smart_contract_service.md new file mode 100644 index 00000000..71ce59b5 --- /dev/null +++ b/documents/api/services/smart_contract_service.md @@ -0,0 +1,57 @@ +## Table of Contents + +- [smart_contract_service.proto](#smart_contract_service-proto) + - [SmartContractService](#proto-SmartContractService) + + + + + +

Top

+ +## smart_contract_service.proto +# Smart Contract Service +gRPC service definitions for calls to the Hedera EVM-compatible +Smart Contract service. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + + + + + + + +### SmartContractService +The Hedera Smart Contract Service (HSCS) provides an interface to an EVM +compatible environment to create, store, manage, and execute smart contract +calls. Smart Contracts implement useful and often highly complex +interactions between individuals, systems, and the distributed ledger. + +| Method Name | Request Type | Response Type | Description | +| ----------- | ------------ | ------------- | ------------| +| createContract | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Create a new smart contract.

If this transaction succeeds, the `ContractID` for the new smart contract SHALL be set in the transaction receipt.
The contract is defined by the initial bytecode (or `initcode`). The `initcode` SHALL be provided either in a previously created file, or in the transaction body itself for very small contracts.
As part of contract creation, the constructor defined for the new smart contract SHALL run with the parameters provided in the `constructorParameters` field.
The gas to "power" that constructor MUST be provided via the `gas` field, and SHALL be charged to the payer for this transaction.
If the contract _constructor_ stores information, it is charged gas for that storage. There is a separate fee in HBAR to maintain that storage until the expiration, and that fee SHALL be added to this transaction as part of the _transaction fee_, rather than gas. | +| updateContract | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Modify a smart contract.
Any change other than updating the expiration time requires that the contract be modifiable (has a valid `adminKey`) and that the transaction be signed by the `adminKey`

Fields _not set_ on the request SHALL NOT be modified. | +| contractCallMethod | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Call a function of a given smart contract, providing function parameter inputs as needed.

Resource ("gas") charges SHALL include all relevant fees incurred by the contract execution, including any storage required.
The total transaction fee SHALL incorporate all of the "gas" actually consumed as well as the standard fees for transaction handling, data transfers, signature verification, etc... | +| contractCallLocalMethod | [Query](#proto-Query) | [Response](#proto-Response) | Call a query function of a given smart contract, providing function parameter inputs as needed.
This is performed locally on the particular node that the client is communicating with. Executing the call locally is faster and less costly, but imposes certain restrictions.

The call MUST NOT change the state of the contract instance. This also precludes any expenditure or transfer of HBAR or other tokens.
The call SHALL NOT have a separate consensus timestamp.
The call SHALL NOT generate a record nor a receipt.
The response SHALL contain the output returned by the function call.

This is generally useful for calling accessor functions which read (query) state without changes or side effects. Any contract call that would use the `STATICCALL` opcode MAY be called via contract call local with performance and cost benefits.

Unlike a ContractCall transaction, the node SHALL always consume the _entire_ amount of offered "gas" in determining the fee for this query, so accurate gas estimation is important. | +| getContractInfo | [Query](#proto-Query) | [Response](#proto-Response) | A standard query to obtain detailed information for a smart contract. | +| ContractGetBytecode | [Query](#proto-Query) | [Response](#proto-Response) | A standard query to read the current bytecode for a smart contract. | +| getBySolidityID | [Query](#proto-Query) | [Response](#proto-Response) | A standard query to obtain account and contract identifiers for a smart contract, given the Solidity identifier for that contract. | +| getTxRecordByContractID | [Query](#proto-Query) | [Response](#proto-Response) |

This query is no longer supported.
This query always returned an empty record list. | +| deleteContract | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Delete a smart contract, and transfer any remaining HBAR balance to a designated account.

If this call succeeds then all subsequent calls to that smart contract SHALL fail.
| +| systemDelete | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Delete a smart contract, as a system-initiated deletion, this SHALL NOT transfer balances.

This call is an administrative function of the Hedera network, and SHALL require network administration authorization.
This transaction MUST be signed by one of the network administration accounts (typically `0.0.2` through `0.0.59`, as defined in the `api-permission.properties` file).
If this call succeeds then all subsequent calls to that smart contract SHALL fail.
| +| systemUndelete | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Un-Delete a smart contract, returning it (mostly) to its state prior to deletion.

The contract to be restored MUST have been deleted via `systemDelete`. If the contract was deleted via `deleteContract`, it SHALL NOT be recoverable.

This call is an administrative function of the Hedera network, and SHALL require network administration authorization.
This transaction MUST be signed by one of the network administration accounts (typically `0.0.2` through `0.0.59`, as defined in the `api-permission.properties` file).
If this call succeeds then subsequent calls to that smart contract MAY succeed.
| +| callEthereum | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Make an Ethereum transaction "call" with all data in Ethereum formats, including the contract alias.

Call data MAY be in the transaction, or stored within a "File".
The caller MAY offer additional gas above what is offered in the call data, but MAY be charged up to 80% of that value if the amount required is less than this "floor" amount. | + + + + + diff --git a/documents/api/services/state/addressbook/node.md b/documents/api/services/state/addressbook/node.md new file mode 100644 index 00000000..7ae40af9 --- /dev/null +++ b/documents/api/services/state/addressbook/node.md @@ -0,0 +1,56 @@ +## Table of Contents + +- [state/addressbook/node.proto](#state_addressbook_node-proto) + - [Node](#com-hedera-hapi-node-state-addressbook-Node) + + + + + +

Top

+ +## state/addressbook/node.proto + + + + + +### Node +A single address book node in the network state. + +Each node in the network address book SHALL represent a single actual +consensus node that is eligible to participate in network consensus. + +Address book nodes SHALL NOT be _globally_ uniquely identified. A given node +is only valid within a single realm and shard combination, so the identifier +for a network node SHALL only be unique within a single realm and shard +combination. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| node_id | [uint64](#uint64) | | A consensus node identifier.

Node identifiers SHALL be globally unique for a given ledger. | +| account_id | [proto.AccountID](#proto-AccountID) | | An account identifier.

This account SHALL be owned by the entity responsible for the node.
This account SHALL be charged transaction fees for any transactions that are submitted to the network by this node and fail due diligence checks.
This account SHALL be paid the node portion of transaction fees for transactions submitted by this node. | +| description | [string](#string) | | A short description of the node.

This value, if set, SHALL NOT exceed 100 bytes when encoded as UTF-8. | +| gossip_endpoint | [proto.ServiceEndpoint](#proto-ServiceEndpoint) | repeated | A list of service endpoints for gossip.

These endpoints SHALL represent the published endpoints to which other consensus nodes may _gossip_ transactions.
If the network configuration value `gossipFqdnRestricted` is set, then all endpoints in this list SHALL supply only IP address.
If the network configuration value `gossipFqdnRestricted` is _not_ set, then endpoints in this list MAY supply either IP address or FQDN, but SHALL NOT supply both values for the same endpoint.
This list SHALL NOT be empty.
This list SHALL NOT contain more than `10` entries.
The first two entries in this list SHALL be the endpoints published to all consensus nodes.
All other entries SHALL be reserved for future use. | +| service_endpoint | [proto.ServiceEndpoint](#proto-ServiceEndpoint) | repeated | A list of service endpoints for client calls.

These endpoints SHALL represent the published endpoints to which clients may submit transactions.
These endpoints SHALL specify a port.
Endpoints in this list MAY supply either IP address or FQDN, but SHALL NOT supply both values for the same endpoint.
This list SHALL NOT be empty.
This list SHALL NOT contain more than `8` entries. | +| gossip_ca_certificate | [bytes](#bytes) | | A certificate used to sign gossip events.

This value SHALL be a certificate of a type permitted for gossip signatures.
This value SHALL be the DER encoding of the certificate presented.
This field is REQUIRED and MUST NOT be empty. | +| grpc_certificate_hash | [bytes](#bytes) | | A hash of the node gRPC certificate.

This value MAY be used to verify the certificate presented by the node during TLS negotiation for gRPC.
This value SHALL be a SHA-384 hash.
The TLS certificate to be hashed SHALL first be in PEM format and SHALL be encoded with UTF-8 NFKD encoding to a stream of bytes provided to the hash algorithm.
This field is OPTIONAL. | +| weight | [uint64](#uint64) | | A consensus weight.

Each node SHALL have a weight in consensus calculations.
The consensus weight of a node SHALL be calculated based on the amount of HBAR staked to that node.
Consensus SHALL be calculated based on agreement of greater than `2/3` of the total `weight` value of all nodes on the network. | +| deleted | [bool](#bool) | | A flag indicating this node is deleted.

If this field is set, then this node SHALL NOT be included in the next update of the network address book.
If this field is set, then this node SHALL be immutable and SHALL NOT be modified.
If this field is set, then any `nodeUpdate` transaction to modify this node SHALL fail. | +| admin_key | [proto.Key](#proto-Key) | | An administrative key controlled by the node operator.

This key MUST sign each transaction to update this node.
This field MUST contain a valid `Key` value.
This field is REQUIRED and MUST NOT be set to an empty `KeyList`. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/state/blockrecords/block_info.md b/documents/api/services/state/blockrecords/block_info.md new file mode 100644 index 00000000..ce03043d --- /dev/null +++ b/documents/api/services/state/blockrecords/block_info.md @@ -0,0 +1,61 @@ +## Table of Contents + +- [state/blockrecords/block_info.proto](#state_blockrecords_block_info-proto) + - [BlockInfo](#proto-BlockInfo) + + + + + +

Top

+ +## state/blockrecords/block_info.proto +# Block Info +Information about the most recent block; including block hashes, current and +previous start times, etc... + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in [RFC2119](https://www.ietf.org/rfc/rfc2119) +and clarified in [RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### BlockInfo +Information for a transaction block. + +This includes: +- last block number. +- consensus times for: + - previous block start. + - current block start. + - last handled transaction. +- hash data for a rolling window of 256 blocks. +- whether migration records were produced. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| last_block_number | [int64](#int64) | | A block number.

The block number of the last completed immutable block. | +| first_cons_time_of_last_block | [Timestamp](#proto-Timestamp) | | A consensus timestamp.

The consensus time of the first transaction for the last completed immutable block. | +| block_hashes | [bytes](#bytes) | | A list of the last 256 block hashes.
This is the SHA384 48 byte hashes of the previous 256 blocks, collected in a single byte array.

The first 48 bytes SHALL be the oldest block in the list.
The last 48 bytes SHALL be the newest block, which is the last fully completed immutable block.
This SHALL contain less than 256 block hashes if there are less than 256 preceding blocks; for instance, shortly after network genesis the network will not have processed 256 blocks yet.

This MAY change significantly for Block Stream (HIP TBD). | +| cons_time_of_last_handled_txn | [Timestamp](#proto-Timestamp) | | A consensus timestamp.

The consensus time of the last transaction that was handled by the node within the current block.
This property is how we 'advance the consensus clock'. The node MUST continually set this property to the consensus timestamp for the most recent transaction completed by the node. | +| migration_records_streamed | [bool](#bool) | | A flag indicating that migration records have been published.

This property SHALL be `false` immediately following a node upgrade
This SHALL be set 'true' as migration records, if any, are published. Migration records are typically published "during" the first transaction handled by the node following startup. | +| first_cons_time_of_current_block | [Timestamp](#proto-Timestamp) | | A consensus timestamp.

The consensus time of the first transaction in the current block; necessary for reconnecting nodes to detect when the current block is finished. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/state/blockrecords/running_hashes.md b/documents/api/services/state/blockrecords/running_hashes.md new file mode 100644 index 00000000..ff1b7336 --- /dev/null +++ b/documents/api/services/state/blockrecords/running_hashes.md @@ -0,0 +1,54 @@ +## Table of Contents + +- [state/blockrecords/running_hashes.proto](#state_blockrecords_running_hashes-proto) + - [RunningHashes](#proto-RunningHashes) + + + + + +

Top

+ +## state/blockrecords/running_hashes.proto +# Running Hashes +The running hash values for the record stream, including current and +three(3) previous values. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in [RFC2119](https://www.ietf.org/rfc/rfc2119) +and clarified in [RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### RunningHashes +The running hash of transaction records and the previous `3` running hashes. + +All hashes are 48 byte SHA384 hash values. If the running hashes do not +exist yet (for example, at genesis) then each not-yet-available value SHALL +be empty (zero-length) bytes. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| running_hash | [bytes](#bytes) | | A running hash of all record stream items. | +| n_minus_1_running_hash | [bytes](#bytes) | | The previous running hash of all record stream items. | +| n_minus_2_running_hash | [bytes](#bytes) | | The previous, previous running hash of all record stream items. | +| n_minus_3_running_hash | [bytes](#bytes) | | The previous, previous, previous running hash of all record stream items. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/state/common.md b/documents/api/services/state/common.md new file mode 100644 index 00000000..fd9770a2 --- /dev/null +++ b/documents/api/services/state/common.md @@ -0,0 +1,73 @@ +## Table of Contents + +- [state/common.proto](#state_common-proto) + - [EntityIDPair](#proto-EntityIDPair) + - [EntityNumber](#proto-EntityNumber) + + + + + +

Top

+ +## state/common.proto +# State Common +Two older messages used in rare cases. +- EntityNumber is used to store The last used entity number in state, so + that all entities in state have unique entity numbers, even across types. +- EntityIDPair is used to store a Token/Account pair in certain rare cases. + +Where possible, these messages SHOULD NOT be used. A primitive `int64` or +`google.protobuf.Int64Value` wrapper is preferred instead of `EntityNumber +and `TokenAssociation` is preferred instead of `EntityIDPair`. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in [RFC2119](https://www.ietf.org/rfc/rfc2119) +and clarified in [RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### EntityIDPair +A Pair of AccountID and TokenID.
+This is used as a key in certain cases. + +The TokenAssociation message should be used instead of this, when possible. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| account_id | [AccountID](#proto-AccountID) | | An account identifier for the associated account. | +| token_id | [TokenID](#proto-TokenID) | | A token identifier for the associated token. | + + + + + + + + +### EntityNumber +A single 64-bit number identifying a Hedera native entity. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| number | [int64](#int64) | | The entity number to store. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/state/congestion/congestion_level_starts.md b/documents/api/services/state/congestion/congestion_level_starts.md new file mode 100644 index 00000000..3c4ea36c --- /dev/null +++ b/documents/api/services/state/congestion/congestion_level_starts.md @@ -0,0 +1,57 @@ +## Table of Contents + +- [state/congestion/congestion_level_starts.proto](#state_congestion_congestion_level_starts-proto) + - [CongestionLevelStarts](#proto-CongestionLevelStarts) + + + + + +

Top

+ +## state/congestion/congestion_level_starts.proto +# Congestion timestamps +The timestamp values indicating when congestion pricing changed. + + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in [RFC2119](https://www.ietf.org/rfc/rfc2119) +and clarified in [RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### CongestionLevelStarts +Two lists of congestion pricing level "start" times. Each list details the +start of each time period when the congestion pricing level changed +(increasing, or decreasing, the congestion fee multiplier). + +> Review Question +>> What prunes these lists? +> +>> Do these grow indefinitely? +> +>> Are these two lists the same size? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| generic_level_starts | [Timestamp](#proto-Timestamp) | repeated | Timestamps for each point where "entity utilization" congestion pricing levels changed.

If congestion pricing has not occurred then this SHALL contain a single timestamp of value 0. | +| gas_level_starts | [Timestamp](#proto-Timestamp) | repeated | Timestamps for each point where "gas utilization" congestion pricing levels changed.

If congestion pricing has not occurred then this SHALL contain a single timestamp of value 0. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/state/consensus/topic.md b/documents/api/services/state/consensus/topic.md new file mode 100644 index 00000000..b47b75ca --- /dev/null +++ b/documents/api/services/state/consensus/topic.md @@ -0,0 +1,67 @@ +## Table of Contents + +- [state/consensus/topic.proto](#state_consensus_topic-proto) + - [Topic](#proto-Topic) + + + + + +

Top

+ +## state/consensus/topic.proto +# HCS Topic Information +The current network state of an Hedera Consensus Service (HCS) Topic. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in [RFC2119](https://www.ietf.org/rfc/rfc2119) +and clarified in [RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### Topic +Representation of an Hedera Consensus Service(HCS) topic. + +As with all network entities, a topic has a unique entity number, which is +usually given along with the network's shard and realm in the form of a +shard.realm.number id.
+An HCS topic is an ordered logical stream of messages united and secured by +a running hash of those messages. The integrity of any message on a topic, +and the topic stream as a whole, can always be ascertained from block stream +data by recomputing the running hash across any subset of messages on the +topic.
+The messages on a topic SHALL NOT be stored in network state, but are +available in the network block stream, and may be queried via the +Mirror Node system. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| topic_id | [TopicID](#proto-TopicID) | | The topic's ID.

This value SHALL be unique within the network. | +| sequence_number | [int64](#int64) | | The number of messages sent to the topic. | +| expiration_second | [int64](#int64) | | The expiration time for this topic, in seconds since the epoch.

For this purpose, `epoch` SHALL be the UNIX epoch with 0 at `1970-01-01T00:00:00.000Z`. | +| auto_renew_period | [int64](#int64) | | The number of seconds for which the topic will be automatically renewed upon expiring (if it has a valid auto-renew account). | +| auto_renew_account_id | [AccountID](#proto-AccountID) | | The id of the account (if any) that the network will attempt to charge fees to complete auto-renewal of this topic, upon expiration. | +| deleted | [bool](#bool) | | A flag indicating that this topic is deleted. | +| running_hash | [bytes](#bytes) | | The current running hash of this topic.

This 48-byte field is the output of a SHA-384 digest with input data determined by the current version of the running hash algorithm used by the network.
All topics in state SHALL use running hash algorithm version `3`.
The bytes of each uint64 or uint32 encoded for the hash input MUST be in Big-Endian format.


If the algorithm version is '3', then the input data to the SHA-384 digest are, in order:
  1. The previous running hash of the topic (48 bytes)
  2. The `topicRunningHashVersion` (8 bytes)
  3. The payer account's shard (8 bytes)
  4. The payer account's realm (8 bytes)
  5. The payer account's number (8 bytes)
  6. The topic's shard (8 bytes)
  7. The topic's realm (8 bytes)
  8. The topic's number (8 bytes)
  9. The number of seconds since the epoch when the `ConsensusSubmitMessage` reached consensus (8 bytes)
  10. The number of nanoseconds within the second when the `ConsensusSubmitMessage` reached consensus (4 bytes)
  11. The `topicSequenceNumber` (8 bytes)
  12. The output of a SHA-384 digest of the message bytes from the `ConsensusSubmitMessage` (48 bytes)
Note that older messages on a topic, which are available in the block stream, MAY use older algorithm versions, and the block stream record incorporates a running hash version field to ensure the correct hash calculation for each such historical message.
| +| memo | [string](#string) | | A short description of this topic.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8. | +| admin_key | [Key](#proto-Key) | | Access control for modification of the topic.

If this field is set, that key MUST sign each message to update or delete this topic.
A topic without an admin key SHALL be immutable, except for expiration and renewal.
If this field is not set, the `auto_renew_account_id` MUST NOT be set. | +| submit_key | [Key](#proto-Key) | | Access control for message submission to the topic.

If this field is set, that key MUST sign each consensus submit message for this topic. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/state/contract/bytecode.md b/documents/api/services/state/contract/bytecode.md new file mode 100644 index 00000000..39b95b1c --- /dev/null +++ b/documents/api/services/state/contract/bytecode.md @@ -0,0 +1,49 @@ +## Table of Contents + +- [state/contract/bytecode.proto](#state_contract_bytecode-proto) + - [Bytecode](#proto-Bytecode) + + + + + +

Top

+ +## state/contract/bytecode.proto +# EVM Bytecode +The verified bytecode of an EVM contract for the Hedera Smart Contract service. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in [RFC2119](https://www.ietf.org/rfc/rfc2119) +and clarified in [RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### Bytecode +The bytecode for a contract account. + +This is not referred to by any other protocol buffer, but is used internally +within the Hedera Node software. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| code | [bytes](#bytes) | | The raw bytes (not hex-encoded) of a contract's bytecode. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/state/contract/storage_slot.md b/documents/api/services/state/contract/storage_slot.md new file mode 100644 index 00000000..c0b982da --- /dev/null +++ b/documents/api/services/state/contract/storage_slot.md @@ -0,0 +1,73 @@ +## Table of Contents + +- [state/contract/storage_slot.proto](#state_contract_storage_slot-proto) + - [SlotKey](#proto-SlotKey) + - [SlotValue](#proto-SlotValue) + + + + + +

Top

+ +## state/contract/storage_slot.proto +# EVM Contract Slot +Information regarding EVM storage "slot"s for the +Hedera Smart Contract service. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in [RFC2119](https://www.ietf.org/rfc/rfc2119) +and clarified in [RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### SlotKey +The key of a storage slot. A slot is scoped to a specific contract ID. + +For each contract, its EVM storage is a mapping of 256-bit keys (or "words") +to 256-bit values. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| contractID | [ContractID](#proto-ContractID) | | The Contract ID of the contract that owns (and pays for) this slot. | +| key | [bytes](#bytes) | | The EVM key of this slot, left-padded with zeros to form a 256-bit word. | + + + + + + + + +### SlotValue +The value of a contract storage slot. For the EVM, this is a single "word". + +Because we iterate through all the storage slots for an expired contract +when purging it from state, our slot values also include the words of the +previous and next keys in this contract's storage "virtual linked list". + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| value | [bytes](#bytes) | | The EVM value in this slot, left-padded with zeros to form a 256-bit word. | +| previous_key | [bytes](#bytes) | | The word of the previous key in this contract's storage list (if any). | +| next_key | [bytes](#bytes) | | The word of the next key in this contract's storage list (if any). | + + + + + + + + + + + + + + + diff --git a/documents/api/services/state/file/file.md b/documents/api/services/state/file/file.md new file mode 100644 index 00000000..82648266 --- /dev/null +++ b/documents/api/services/state/file/file.md @@ -0,0 +1,68 @@ +## Table of Contents + +- [state/file/file.proto](#state_file_file-proto) + - [File](#proto-File) + + + + + +

Top

+ +## state/file/file.proto +# File +A "file" in the distributed ledger is a stream of bytes. These bytes may +contain any data, and are limited in length based on network configuration +(for example, 1048576). + + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in [RFC2119](https://www.ietf.org/rfc/rfc2119) +and clarified in [RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### File +Representation of an Hedera File Service `file`. + +Files offer a place to store additional data, much more than is available in +other entities, for use with smart contracts, non-fungible tokens, etc... +As with all network entities, a file has a unique entity number, which is +given along with the network's shard and realm in the form of a +shard.realm.number id. + +> Review Question +>> File lacks auto renewal (account and period). We need to add that here, +>> and also to create and update transactions. +> +>> The keys field is weird and really needs to change to adminKey and +>> deleteKey to be more correct and match other things. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| file_id | [FileID](#proto-FileID) | | This file's ID within the global network state.

This value SHALL be unique within the network. | +| expiration_second | [int64](#int64) | | The file's expiration time in seconds since the epoch.

For this purpose, `epoch` SHALL be the UNIX epoch with 0 at `1970-01-01T00:00:00.000Z`. | +| keys | [KeyList](#proto-KeyList) | | A list of keys that MUST sign any transaction to update this file.

Only _one_ of these keys must sign a transaction to delete the file.
This field SHOULD NOT be `null` or an empty list. | +| contents | [bytes](#bytes) | | The contents of the file.

This SHALL be limited to the current maximum file size; typically no more than 1 Megabyte (1048576 bytes). | +| memo | [string](#string) | | A short description of the file.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8. | +| deleted | [bool](#bool) | | A flag indicating that this file is deleted.

The `contents` of a deleted "regular" file SHALL be an empty (zero length) bytes. | +| pre_system_delete_expiration_second | [int64](#int64) | | The pre-system-delete expiration time of a deleted "system" file, in seconds.

This field SHALL contain the original expiration time of a "system" file that is deleted. This SHOULD be used to restore that expiration time if the file is subsequently "un-deleted" before it is purged from the system.
A "regular" file cannot be "un-deleted", so this field SHALL NOT be set for those files. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/state/primitives.md b/documents/api/services/state/primitives.md new file mode 100644 index 00000000..67eaa34b --- /dev/null +++ b/documents/api/services/state/primitives.md @@ -0,0 +1,114 @@ +## Table of Contents + +- [state/primitives.proto](#state_primitives-proto) + - [ProtoBoolean](#proto-ProtoBoolean) + - [ProtoBytes](#proto-ProtoBytes) + - [ProtoInteger](#proto-ProtoInteger) + - [ProtoLong](#proto-ProtoLong) + - [ProtoString](#proto-ProtoString) + + + + + +

Top

+ +## state/primitives.proto +# Primitives +Primitive value wrapper messages. + +These SHALL be used only for situations where the entire value to be stored +in state is a single primitive. These MUST NOT ever be used as components of +another message; use the protobuf type instead. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in [RFC2119](https://www.ietf.org/rfc/rfc2119) +and clarified in [RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ProtoBoolean +A single boolean with no particular meaning. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| value | [bool](#bool) | | | + + + + + + + + +### ProtoBytes +A single byte array with no particular meaning. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| value | [bytes](#bytes) | | | + + + + + + + + +### ProtoInteger +A single 32-bit number with no particular meaning. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| value | [int32](#int32) | | | + + + + + + + + +### ProtoLong +A single 64-bit number with no particular meaning. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| value | [int64](#int64) | | | + + + + + + + + +### ProtoString +A single string with no particular meaning. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| value | [string](#string) | | | + + + + + + + + + + + + + + + diff --git a/documents/api/services/state/recordcache/recordcache.md b/documents/api/services/state/recordcache/recordcache.md new file mode 100644 index 00000000..d0b07040 --- /dev/null +++ b/documents/api/services/state/recordcache/recordcache.md @@ -0,0 +1,97 @@ +## Table of Contents + +- [state/recordcache/recordcache.proto](#state_recordcache_recordcache-proto) + - [TransactionReceiptEntries](#proto-TransactionReceiptEntries) + - [TransactionReceiptEntry](#proto-TransactionReceiptEntry) + - [TransactionRecordEntry](#proto-TransactionRecordEntry) + + + + + +

Top

+ +## state/recordcache/recordcache.proto +# Record Cache +The Record Cache holds transaction records for a short time, and is the +source for responses to `transactionGetRecord` and `transactionGetReceipt` +queries. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in [RFC2119](https://www.ietf.org/rfc/rfc2119) +and clarified in [RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### TransactionReceiptEntries +As transactions are handled and receipts are created, they are stored in state for a configured time +limit (perhaps, for example, 3 minutes). During this time window, any client can query the node and get the +receipt for the transaction. The TransactionReceiptEntries is the object stored in state with this information. +This object contains a list of TransactionReceiptEntry objects. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| entries | [TransactionReceiptEntry](#proto-TransactionReceiptEntry) | repeated | | + + + + + + + + +### TransactionReceiptEntry +An entry in the record cache with the receipt for a transaction. + +When a transaction is handled a receipt is created. This receipt must be +stored in state for a configured time limit (e.g. 3 minutes). +During this time window, any client can query the node and retrieve the +receipt. This message, then, is the entry stored in state that enables +returning this receipt information. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| node_id | [uint64](#uint64) | | A node identifier.
This identifies the node that submitted the transaction to consensus. The value is the identifier as known to the current address book.

Valid node identifiers SHALL be between 0 and 263-1, inclusive. | +| transaction_id | [TransactionID](#proto-TransactionID) | | The id of the submitted transaction. | +| status | [ResponseCodeEnum](#proto-ResponseCodeEnum) | | The resulting status of handling the transaction. | + + + + + + + + +### TransactionRecordEntry +As transactions are handled and records and receipts are created, they are +stored in state for a configured time period (for example, 3 minutes). +During this time, any client can query the node and get the record or receipt +for the transaction. The `TransactionRecordEntry` is the object stored in +state with this information. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| node_id | [int64](#int64) | | A node identifier.
This identifier is the node, as known to the address book, that submitted the transaction for consensus.

This SHALL be a whole number. | +| payer_account_id | [AccountID](#proto-AccountID) | | An Account identifier for the payer for the transaction.

This MAY be the same as the account ID within the Transaction ID of the record, or it MAY be the account ID of the node that submitted the transaction to consensus if the account ID in the Transaction ID was not able to pay. | +| transaction_record | [TransactionRecord](#proto-TransactionRecord) | | A transaction record for the transaction. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/state/schedule/schedule.md b/documents/api/services/state/schedule/schedule.md new file mode 100644 index 00000000..5e824a5a --- /dev/null +++ b/documents/api/services/state/schedule/schedule.md @@ -0,0 +1,79 @@ +## Table of Contents + +- [state/schedule/schedule.proto](#state_schedule_schedule-proto) + - [Schedule](#proto-Schedule) + - [ScheduleList](#proto-ScheduleList) + + + + + +

Top

+ +## state/schedule/schedule.proto +# Scheduled Transaction +Information regarding Scheduled Transactions. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in [RFC2119](https://www.ietf.org/rfc/rfc2119) +and clarified in [RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### Schedule +Representation of a Hedera Schedule entry in the network Merkle tree. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| schedule_id | [ScheduleID](#proto-ScheduleID) | | This schedule's ID within the global network state.

This value SHALL be unique within the network. | +| deleted | [bool](#bool) | | A flag indicating this schedule is deleted.

A schedule SHALL either be executed or deleted, but never both. | +| executed | [bool](#bool) | | A flag indicating this schedule has executed.

A schedule SHALL either be executed or deleted, but never both. | +| wait_for_expiry | [bool](#bool) | | A schedule flag to wait for expiration before executing.

A schedule SHALL be executed immediately when all necessary signatures are gathered, unless this flag is set.
If this flag is set, the schedule SHALL wait until the consensus time reaches `expiration_time_provided`, when signatures MUST again be verified. If all required signatures are present at that time, the schedule SHALL be executed. Otherwise the schedule SHALL expire without execution.

Note that a schedule is always removed from state after it expires, regardless of whether it was executed or not. | +| memo | [string](#string) | | A short description for this schedule.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8. | +| scheduler_account_id | [AccountID](#proto-AccountID) | | The scheduler account for this schedule.

This SHALL be the account that submitted the original ScheduleCreate transaction. | +| payer_account_id | [AccountID](#proto-AccountID) | | The explicit payer account for the scheduled transaction.

If set, this account SHALL be added to the accounts that MUST sign the schedule before it may execute. | +| admin_key | [Key](#proto-Key) | | The admin key for this schedule.

This key, if set, MUST sign any `schedule_delete` transaction.
If not set, then this schedule SHALL NOT be deleted, and any `schedule_delete` transaction for this schedule SHALL fail. | +| schedule_valid_start | [Timestamp](#proto-Timestamp) | | The transaction valid start value for this schedule.

This MUST be set, and SHALL be copied from the `TransactionID` of the original `schedule_create` transaction. | +| provided_expiration_second | [int64](#int64) | | The requested expiration time of the schedule if provided by the user.

If not provided in the `schedule_create` transaction, this SHALL be set to a default value equal to the current consensus time, forward offset by the maximum schedule expiration time in the current dynamic network configuration (typically 62 days).
The actual `calculated_expiration_second` MAY be "earlier" than this, but MUST NOT be later. | +| calculated_expiration_second | [int64](#int64) | | The calculated expiration time of the schedule.

This SHALL be calculated from the requested expiration time in the `schedule_create` transaction, and limited by the maximum expiration time in the current dynamic network configuration (typically 62 days).

The schedule SHALL be removed from global network state after the network reaches a consensus time greater than or equal to this value. | +| resolution_time | [Timestamp](#proto-Timestamp) | | The consensus timestamp of the transaction that executed or deleted this schedule.

This value SHALL be set to the `current_consensus_time` when a `schedule_delete` transaction is completed.
This value SHALL be set to the `current_consensus_time` when the scheduled transaction is executed, either as a result of gathering the final required signature, or, if long-term schedule execution is enabled, at the requested execution time. | +| scheduled_transaction | [SchedulableTransactionBody](#proto-SchedulableTransactionBody) | | The scheduled transaction to execute.

This MUST be one of the transaction types permitted in the current value of the `schedule.whitelist` in the dynamic network configuration. | +| original_create_transaction | [TransactionBody](#proto-TransactionBody) | | The full transaction that created this schedule.

This is primarily used for duplicate schedule create detection. This is also the source of the parent transaction ID, from which the child transaction ID is derived when the `scheduled_transaction` is executed. | +| signatories | [Key](#proto-Key) | repeated | All of the "primitive" keys that have already signed this schedule.

The scheduled transaction SHALL NOT be executed before this list is sufficient to "activate" the required keys for the scheduled transaction.
A Key SHALL NOT be stored in this list unless the corresponding private key has signed either the original `schedule_create` transaction or a subsequent `schedule_sign` transaction intended for, and referencing to, this specific schedule.

The only keys stored are "primitive" keys (ED25519 or ECDSA_SECP256K1) in order to ensure that any key list or threshold keys are correctly handled, regardless of signing order, intervening changes, or other situations. The `scheduled_transaction` SHALL execute only if, at the time of execution, this list contains sufficient public keys to satisfy the full requirements for signature on that transaction. | + + + + + + + + +### ScheduleList +A message for storing a list of schedules in state. + +This is used to store lists of schedules that expire at a particular time or +that have the same simplified hash code. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| schedules | [Schedule](#proto-Schedule) | repeated | A list of schedules, in encounter order. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/state/throttles/throttle_usage_snapshots.md b/documents/api/services/state/throttles/throttle_usage_snapshots.md new file mode 100644 index 00000000..4e819dc9 --- /dev/null +++ b/documents/api/services/state/throttles/throttle_usage_snapshots.md @@ -0,0 +1,72 @@ +## Table of Contents + +- [state/throttles/throttle_usage_snapshots.proto](#state_throttles_throttle_usage_snapshots-proto) + - [ThrottleUsageSnapshot](#proto-ThrottleUsageSnapshot) + - [ThrottleUsageSnapshots](#proto-ThrottleUsageSnapshots) + + + + + +

Top

+ +## state/throttles/throttle_usage_snapshots.proto +# Throttle Snapshots +Point-in-time information regarding throttle usage. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in [RFC2119](https://www.ietf.org/rfc/rfc2119) +and clarified in [RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ThrottleUsageSnapshot +A single snapshot of the used throttle capacity for a throttle and point in +time. + +> Question: +>> What throttle does this apply to? How is that determined? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| used | [int64](#int64) | | Used throttle capacity. | +| last_decision_time | [Timestamp](#proto-Timestamp) | | The time at which the this snapshot of capacity was calculated.
Stored as an offset from the `epoch`.

For this purpose, `epoch` SHALL be the UNIX epoch with 0 at `1970-01-01T00:00:00.000Z`. | + + + + + + + + +### ThrottleUsageSnapshots +All point-in-time snapshots of throttle usage for TPS and "gas" throttle +values for a given point in time. + +> Question: +>> What point in time? Should this store consensus timestamp here? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| tps_throttles | [ThrottleUsageSnapshot](#proto-ThrottleUsageSnapshot) | repeated | A list of snapshots for TPS throttles.

Question:
What is the order?
| +| gas_throttle | [ThrottleUsageSnapshot](#proto-ThrottleUsageSnapshot) | | A single snapshot for the gas throttle. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/state/token/account.md b/documents/api/services/state/token/account.md new file mode 100644 index 00000000..912b123c --- /dev/null +++ b/documents/api/services/state/token/account.md @@ -0,0 +1,258 @@ +## Table of Contents + +- [state/token/account.proto](#state_token_account-proto) + - [Account](#proto-Account) + - [AccountApprovalForAllAllowance](#proto-AccountApprovalForAllAllowance) + - [AccountCryptoAllowance](#proto-AccountCryptoAllowance) + - [AccountFungibleTokenAllowance](#proto-AccountFungibleTokenAllowance) + + + + + +

Top

+ +## state/token/account.proto +# Account. +This is a single account within the Hedera network. An Account is the +primary entity representing ownership of assets tracked on the ledger. +Account Allowances are also described here, and these represent permission +granted to an account to transfer assets owned by a different account which +granted the "allowance". Allowances specify the assets and amounts which may +be transferred. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### Account +A single Account in the Hedera distributed ledger. + +Each Account has a unique three-part identifier, a Key, and one or more token +balances. + +Accounts also have an alias, which has multiple forms, and may be set +automatically. + +Several additional items are associated with the Account to enable full +functionality. + +Assets are represented as linked-lists with only the "head" item referenced +directly in the Account, and the remaining items are accessible via the +token relation or unique tokens maps. + +Accounts, as most items in the network, have an expiration time, recorded as +seconds since the epoch, and must be "renewed" for a small fee at expiration. +This helps to reduce the amount of inactive accounts retained in state. +Another account may be designated to pay any renewal fees and automatically +renew the account for (by default) 30-90 days at a time as a means to +optionally ensure important accounts remain active. + +Accounts may participate in securing the network by "staking" the account +balances to a particular network node, and receive a portion of network fees +as a reward. An account may optionally decline these rewards but still stake +its balances. + +An account may optionally require that inbound transfer transactions be +signed by that account as receiver (in addition to the sender's signature). + +As with all network entities, Account ID is represented as shard.realm.X. +Alias and contractId are additional identifiers used to connect accounts to +transactions before the account is fully enabled, or in EVM contracts. +--- +There is considerable complexity with `alias` (aka `evm_address`) for +Accounts. Much of this comes from the existence of a "hidden" alias for +almost all accounts, and the reuse of the alias field for both EVM reference +and "automatic" account creation. + +For the purposes of this specification, we will use the following terms for +clarity. + - `key_alias` is the account public key as a protobuf serialized message + and used for auto-creation and subsequent lookup. This is only valid if + the account key is a + single `primitive` key, either ED25519 or ECDSA_SECP256K1. + - `evm_address` exists for every account and is one of + - `contract_address`, which is the 20 byte EVM contract address per + EIP-1014 + - `evm_key_address`, which is the keccak-256 hash of a ECDSA_SECP256K1 + `primitive` key. + - This is for accounts lazy-created from EVM public keys, when the + corresponding ECDSA_SECP256K1 public key is presented in a + transaction signed by the private key for that public key, the + account is created that key assigned, and the protobuf-serialized + form is set as the account alias. + - `long_zero`, is a synthetic 20 byte address inferred for "normally" + created accounts. It is constructed from the "standard" AccountID as + follows. + - 4 byte big-endian shard number + - 8 byte big-endian realm number + - 8 byte big-endian entity number + +The `alias` field in the `Account` message SHALL contain one of four values +for any given account. + - The `key_alias`, if the account was created by transferring HBAR to the + account referenced by `key_alias`. + - The `evm_key_address` if the account was created from an EVM public key + - The `contract_address` if the account belongs to an EVM contract + - Not-Set/null/Bytes.EMPTY (collectively `null`) if the account was + created normally +If the `alias` field of an `Account` is any form of `null`, then the account +MAY be referenced by `alias` in an `AccountID` by using the `long_zero` +address for the account. This "hidden default" alias SHALL NOT be stored, +but is synthesized by the node software as needed, and may be synthesized by +an EVM contract or client software as well. + +> Note
+>> The use and meaning of `alias` is expected to change significantly as a +>> result of HIP-631. + +An AccountID in a transaction MAY reference an `Account` with +`shard`.`realm`.`alias`.
+If the account `alias` field is set for an Account, that value SHALL be the +account alias.
+If the account `alias` field is not set for an Account, the `long_zero` +alias SHALL be the account alias. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| account_id | [AccountID](#proto-AccountID) | | The unique ID of this account.

An account ID, when assigned to this field, SHALL be of the form `shard.realm.number`.
Transactions MAY reference the account by alias, but the account itself MUST always have a purely numeric identifier. This numeric ID is the value used to reference the account in query responses, transaction receipts, transaction records, and the block stream. | +| alias | [bytes](#bytes) | | An account EVM alias.

This is a value used in some contexts to reference an account when the numeric account identifier is not available.
This field, when set to a non-default value, is immutable and SHALL NOT be changed. | +| key | [Key](#proto-Key) | | The key to be used to sign transactions from this account, if any.

This key SHALL NOT be set for hollow accounts until the account is finalized.
This key SHALL be set on all other accounts, except for certain immutable accounts (0.0.800 and 0.0.801) necessary for network function and otherwise secured by the governing council. | +| expiration_second | [int64](#int64) | | The current expiration time of this account, in seconds since the epoch.

For this purpose, `epoch` SHALL be the UNIX epoch with 0 at `1970-01-01T00:00:00.000Z`.
This account SHALL be due standard renewal fees when the network consensus time exceeds this time.
If rent and expiration are enabled for the network, and automatic renewal is enabled for this account, renewal fees SHALL be charged after this time, and, if charged, the expiration time SHALL be extended for another renewal period.
This account MAY be expired and removed from state at any point after this time if not renewed.
An account holder MAY extend this time by submitting an account update transaction to modify expiration time, subject to the current maximum expiration time for the network. | +| tinybar_balance | [int64](#int64) | | The HBAR balance of this account, in tinybar (10-8 HBAR).

This value is a signed integer for efficiency, but MUST always be a whole number. | +| memo | [string](#string) | | A short description of this account.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8. | +| deleted | [bool](#bool) | | A boolean indicating that this account is deleted. | +| staked_to_me | [int64](#int64) | | The amount of HBAR staked to this account by others. | +| stake_period_start | [int64](#int64) | | If this account stakes to another account, this value SHALL be set to the time when the current period for staking and reward calculations began. | +| staked_account_id | [AccountID](#proto-AccountID) | | An identifier for the account to which this account is staking its balances as a proxy.

If this account is not currently staking its balances, then this field, if set, SHALL be the sentinel value of `0.0.0`. | +| staked_node_id | [int64](#int64) | | An identifier for the node this account is staked to.

If this account is not currently staking its balances, then this field, if set, SHALL be the sentinel value of `-1`. Wallet software SHOULD surface staking issues to users and provide a simple mechanism to update staking to a new node ID in the event the prior staked node ID ceases to be valid.

Note: node IDs do fluctuate as node operators change. The Account owner MUST submit a new transaction to change this value if the current node ID changes or ceases to operate as a node. An account with an invalid `staked_node_id` SHALL NOT participate in staking until the `staked_node_id` is updated to a valid node ID.
| +| decline_reward | [bool](#bool) | | A boolean indicating that this account has chosen to decline rewards for staking its balances.

This account MAY still stake its balances, but SHALL NOT receive reward payments for doing so. | +| receiver_sig_required | [bool](#bool) | | A boolean indicating that the account requires a receiver signature for inbound token transfer transactions.

If this value is `true` then a transaction to transfer tokens to this account SHALL NOT succeed unless this account has signed the transfer transaction. | +| head_token_id | [TokenID](#proto-TokenID) | | A token ID at the head of the linked list for this account from the token relations map.
The token relations are connected by including the "next" and "previous" TokenID in each TokenRelation message. The "head" item in that list is found by looking up the TokenRelation with this Account's account_id and this head_token_id. Each subsequent item in the list is found via similar lookup with both an AccountID and a TokenID. | +| head_nft_id | [NftID](#proto-NftID) | | A NftID at the head of the linked list for this account from the unique tokens map.
The unique token relations are connected by including the "next" and "previous" NftID in each Nft message. The "head" item in that list is found by looking up the Nft with ID matching this head_nft_id. Each subsequent item in the list is found via similar lookup with the next or previous NftID. | +| head_nft_serial_number | [int64](#int64) | | A serial number in the NftID at the head of the linked list for this account from unique tokens map.

This MUST match the `serial_number` field of `head_nft_id`. | +| number_owned_nfts | [int64](#int64) | | A number of non-fungible tokens (NTFs) owned by the account. | +| max_auto_associations | [int32](#int32) | | A maximum for the number of tokens that can be automatically associated with this account.

If this is less than or equal to `used_auto_associations` (or 0), then this account MUST manually associate with a token before transacting in that token.
This value may also be `-1` to indicate no limit.
This value MUST NOT be less than `-1`. | +| used_auto_associations | [int32](#int32) | | A count of used auto-association slots.

If this is greater than, or equal to, the current value of `max_auto_associations`, then this account MUST manually associate with a new token before transacting in that token. | +| number_associations | [int32](#int32) | | A count of tokens associated with this account.

This value determines a portion of the renewal fee for this account. | +| smart_contract | [bool](#bool) | | A boolean indicating that this account is owned by a smart contract. | +| number_positive_balances | [int32](#int32) | | A count of tokens with a positive balance associated with this account.

If the account has a positive balance in any token, it SHALL NOT be deleted. | +| ethereum_nonce | [int64](#int64) | | A nonce of this account for Ethereum interoperability. | +| stake_at_start_of_last_rewarded_period | [int64](#int64) | | An amount of HBAR staked by this account at the start of the last reward period. | +| auto_renew_account_id | [AccountID](#proto-AccountID) | | An account identifier for automatic renewal.
This is the identifier of another account, in the same shard and realm as this account, that has signed a transaction allowing the network to use its balance, if needed, to automatically extend this account's expiration time during automatic renewal processing.

If this is set, and this account lack sufficient HBAR balance to pay renewal fees when due, then the network SHALL deduct the necessary fees from the designated auto renew account, if that account has sufficient balance. | +| auto_renew_seconds | [int64](#int64) | | A count of the number of seconds to extend this account's expiration.

The network SHALL extend the account's expiration by this number of seconds, if funds are available, upon automatic renewal.
This SHALL NOT apply if the account is already deleted upon expiration.
If this is not provided in an allowed range on account creation, the transaction SHALL fail with INVALID_AUTO_RENEWAL_PERIOD. The default values for the minimum period and maximum period are currently 30 days and 90 days, respectively. | +| contract_kv_pairs_number | [int32](#int32) | | A count of smart contract key-value pairs.
If this account is a smart-contract, this is the number of key-value pairs stored on the contract.

If this account is not a smart contract, this field SHALL NOT be used.
This value SHALL determine a portion of the storage rental fees for the contract. | +| crypto_allowances | [AccountCryptoAllowance](#proto-AccountCryptoAllowance) | repeated | A list of crypto (HBAR) allowances approved by this account.

If this is not empty, each allowance SHALL permit a specified "spender" account to spend this account's HBAR balance, up to a designated limit.
This field SHALL permit spending only HBAR balance, not other tokens the account may hold. Allowances for other tokens SHALL be listed in the `token_allowances` field or the `approve_for_all_nft_allowances` field. | +| approve_for_all_nft_allowances | [AccountApprovalForAllAllowance](#proto-AccountApprovalForAllAllowance) | repeated | A list of non-fungible token (NFT) allowances approved by this account.

If this is not empty, each allowance permits a specified "spender" account to transfer _all_ of this account's non-fungible tokens from a particular collection.
Allowances for a specific serial number MUST be directly associated with that specific non-fungible token, rather than the holding account. | +| token_allowances | [AccountFungibleTokenAllowance](#proto-AccountFungibleTokenAllowance) | repeated | A list of fungible token allowances approved by this account.

If this is not empty, each allowance permits a specified "spender" to spend this account's fungible tokens, of the designated type, up to a designated limit. | +| number_treasury_titles | [uint32](#uint32) | | A count of tokens for which this account is the treasury account.

Each native token is initially created with all tokens held by its treasury, and the owner of that account (which may be a smart contract) determines how those tokens are distributed. | +| expired_and_pending_removal | [bool](#bool) | | A flag indicating that the account is expired and pending removal.

When the network checks for entity expiration, it SHALL set this flag if the account expiration time has past and the account has no HBAR sufficient to pay current renewal fees.
If the account has an auto-renew account set with an HBAR balance that could pay for an auto-renewal, then this flag SHALL NOT be set. This ensures the account is not encumbered during the time between expiration and when the auto-renewal processing renews the account. | +| first_contract_storage_key | [bytes](#bytes) | | A contract storage key.
This is the first key in the doubly-linked list of this contract's storage mappings.

This value SHALL be empty if the account is not a contract or the contract has no storage mappings. | +| head_pending_airdrop_id | [PendingAirdropId](#proto-PendingAirdropId) | | A pending airdrop ID.
This is the head of the linked list for this account from the account airdrops map.

The account airdrops SHALL be connected by including the "next" and "previous" `PendingAirdropID` in each `AccountAirdrop` message.
This value SHALL NOT be empty if this account is "sender" for any pending airdrop, and SHALL be empty otherwise. | +| number_pending_airdrops | [uint64](#uint64) | | A number of pending airdrops.

This count SHALL be used to calculate rent _without_ walking the linked list of pending airdrops associated to this account via the `head_pending_airdrop_id` field.
This value MUST be updated for every airdrop, clam, or cancel transaction that designates this account as a receiver.
This number MUST always match the count of entries in the "list" identified by `head_pending_airdrop_id`. | + + + + + + + + +### AccountApprovalForAllAllowance +Permission granted by one account (the "funding" account) to another account +(the "spender" account) that allows the spender to transfer all serial +numbers of a specific non-fungible token (NFT) collection owned by the +funding account.
+This is a broad permission, as it does not matter how many NFTs of the +specified collection the funding account owns, the spender MAY dispose of +any or all of them with this allowance.
+Each token type (typically a collection of NFTs) SHALL require a separate +allowance.
+Allowances for a specific serial number MUST be directly associated with +that specific non-fungible token, rather than the holding account. + +An allowance SHALL NOT transfer any tokens directly, it only permits +transactions signed only by the spender account to transfer any non-fungible +tokens of the specified type owned by the funding account. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| token_id | [TokenID](#proto-TokenID) | | The identifier for the token associated with this allowance.

This token MUST be a non-fungible/unique token. | +| spender_id | [AccountID](#proto-AccountID) | | The identifier for the spending account associated with this allowance.

This account SHALL be permitted to sign transactions to spend tokens of the associated token type from the funding/allowing account. | + + + + + + + + +### AccountCryptoAllowance +Permission granted by one account (the "funding" account) to another account +(the "spender" account) that allows the spender to spend a specified amount +of HBAR owned by the funding account. + +An allowance SHALL NOT transfer any HBAR directly, it only permits +transactions signed only by the spender account to transfer HBAR, up to the +amount specified, from the funding account. + +Once the specified amount is spent, the allowance SHALL be consumed and a +new allowance SHALL be required before that spending account may spend +additional HBAR from the funding account. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| spender_id | [AccountID](#proto-AccountID) | | The identifier for the spending account associated with this allowance.

This account SHALL be permitted to sign transactions to spend HBAR from the funding/allowing account.
This permission SHALL be limited to no more than the specified `amount`. | +| amount | [int64](#int64) | | The maximum amount that the spender account may transfer within the scope of this allowance.

This allowance SHALL be consumed if any combination of transfers authorized via this allowance meet this value in total.
This value MUST be specified in tinybar (i.e. 10-8 HBAR). | + + + + + + + + +### AccountFungibleTokenAllowance +Permission granted by one account (the "funding" account) to another account +(the "spender" account) that allows the spender to spend a specified amount +of a specific non-HBAR fungible token from the balance owned by the funding +account. + +An allowance SHALL NOT transfer any tokens directly, it only permits +transactions signed only by the spender account to transfer tokens of the +specified type, up to the amount specified, from the funding account. + +Once the specified amount is spent, the allowance SHALL be consumed and a +new allowance SHALL be required before that spending account may spend +additional tokens from the funding account. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| token_id | [TokenID](#proto-TokenID) | | The identifier for the token associated with this allowance.

This token MUST be a fungible/common token. | +| spender_id | [AccountID](#proto-AccountID) | | The identifier for the spending account associated with this allowance.

This account SHALL be permitted to sign transactions to spend tokens of the associated token type from the funding/allowing account.
This permission SHALL be limited to no more than the specified `amount`. | +| amount | [int64](#int64) | | The maximum amount that the spender account may transfer within the scope of this allowance.

This allowance SHALL be consumed if any combination of transfers authorized via this allowance meet this value in total.
This value MUST be specified in the smallest units of the relevant token (i.e. 10-decimals whole tokens). | + + + + + + + + + + + + + + + diff --git a/documents/api/services/state/token/network_staking_rewards.md b/documents/api/services/state/token/network_staking_rewards.md new file mode 100644 index 00000000..a627cf86 --- /dev/null +++ b/documents/api/services/state/token/network_staking_rewards.md @@ -0,0 +1,52 @@ +## Table of Contents + +- [state/token/network_staking_rewards.proto](#state_token_network_staking_rewards-proto) + - [NetworkStakingRewards](#proto-NetworkStakingRewards) + + + + + +

Top

+ +## state/token/network_staking_rewards.proto +# Network Staking Rewards +The information needed to calculate the staking rewards for all nodes in +the network. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in [RFC2119](https://www.ietf.org/rfc/rfc2119) +and clarified in [RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### NetworkStakingRewards +An Hedera Token Service staking reward entity. +This stores values related to the aggregate staking rewards for all nodes in +the network. It is calculated at the beginning of each staking period. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| staking_rewards_activated | [bool](#bool) | | A flag indicating that staking rewards are activated on the network.

Among other criteria, this is set to true when the balance of 0.0.800 (the account that pays rewards) reaches a minimum required balance. | +| total_staked_reward_start | [int64](#int64) | | A global snapshot of the `stake_to_reward` value for all nodes at the beginning of the current staking period.

The `stake_to_reward` value is the sum of balance and `staked_to_me` for all accounts staked to a node that do not decline staking rewards.
This is needed for calculating rewards for current staking period without considering changes to `stake_to_reward` within the current staking period.
This value SHALL be reset at the beginning of every staking period. | +| total_staked_start | [int64](#int64) | | A global snapshot of the `stake` value for all nodes at the beginning of the current staking period.

The `stake` value is the sum of balance and `staked_to_me` for all accounts staked to a node, and SHALL NOT consider whether the account has accepted or declined rewards.
This value SHALL be reset at the beginning of every staking period. | +| pending_rewards | [int64](#int64) | | The total staking rewards, in tinybars, that may be collected by all accounts staking to all nodes after the end of this staking period.

This SHALL be calculated assuming that no account "renounces" its rewards by setting `decline_reward` to true, or is ineligible for some other reason.
If a node is removed, the `pending_rewards` value of that node SHALL be subtracted from this value. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/state/token/nft.md b/documents/api/services/state/token/nft.md new file mode 100644 index 00000000..0381f3c1 --- /dev/null +++ b/documents/api/services/state/token/nft.md @@ -0,0 +1,61 @@ +## Table of Contents + +- [state/token/nft.proto](#state_token_nft-proto) + - [Nft](#proto-Nft) + + + + + +

Top

+ +## state/token/nft.proto +# NFT. +This is a single, whole, unique, non-fungible token within the Hedera network. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in [RFC2119](https://www.ietf.org/rfc/rfc2119) +and clarified in [RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### Nft +An Hedera Token Service non-fungible token (NFT).
+Every NFT is a unique instance of a token with non-fungible type. + +The NFT SHALL be identified by token ID and serial number.
+The token treasury account SHALL own all minted NFTs of that token type +initially.
+NFTs owned by the token treasury SHALL NOT be linked into that account's +virtual linked list of NFTs.
+NFTs not owned by the token treasury SHALL be linked into the owner +account's virtual linked list of NFTs. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| nft_id | [NftID](#proto-NftID) | | The id of this NFT, consisting of a Token ID and serial number. | +| owner_id | [AccountID](#proto-AccountID) | | The account or contract id that owns this NFT.

If this NFT is owned by its token type's current treasury account, this value SHALL be zero. | +| spender_id | [AccountID](#proto-AccountID) | | The account or contract id approved to spend this NFT.

If there is no approved spender, this value SHALL be null. | +| mint_time | [Timestamp](#proto-Timestamp) | | The consensus time of the TokenMint that created this NFT as offset from the epoch.

For this purpose, `epoch` SHALL be the UNIX epoch with 0 at `1970-01-01T00:00:00.000Z`. | +| metadata | [bytes](#bytes) | | The metadata bytes for this NFT. This is often a URI value.

This value, if set, SHALL NOT exceed 100 bytes. | +| owner_previous_nft_id | [NftID](#proto-NftID) | | The NFT ID of the previous entry in the current owner's "virtual double-linked list" of owned NFTs.

If the owner of this NFT is the token treasury, this SHALL be unset. | +| owner_next_nft_id | [NftID](#proto-NftID) | | The NFT ID of the next entry in the current owner's "virtual double-linked list" of owned NFTs.

If the owner of this NFT is the token treasury, this SHALL be unset. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/state/token/staking_node_info.md b/documents/api/services/state/token/staking_node_info.md new file mode 100644 index 00000000..356f8472 --- /dev/null +++ b/documents/api/services/state/token/staking_node_info.md @@ -0,0 +1,61 @@ +## Table of Contents + +- [state/token/staking_node_info.proto](#state_token_staking_node_info-proto) + - [StakingNodeInfo](#proto-StakingNodeInfo) + + + + + +

Top

+ +## state/token/staking_node_info.proto +# Staking Node Information +This is an entry describing the staking characteristics of a single active +node. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in [RFC2119](https://www.ietf.org/rfc/rfc2119) +and clarified in [RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### StakingNodeInfo +An Hedera Token Service staking info entity. + +Staking info is per node. Shard and Realm are implied based on the network +address book entry for this node. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| node_number | [int64](#int64) | | The entity number of this node.
The shard and realm numbers are implied, based on the network address book entry for this node.

This value SHALL be unique within a given shard and realm.
This value MAY be repeated across shards and/or realms. | +| min_stake | [int64](#int64) | | The minimum stake, in tinybar, that is required for this node to have a non-zero weight in the network consensus.

If the current value of `stake` is below this value, this node SHALL have a zero weight in network consensus. | +| max_stake | [int64](#int64) | | The maximum stake to this node that is considered to calculate its weight in the network consensus.

If the current `stake` value is above this limit, the excess staked HBAR SHALL NOT be considered when determining consensus weight. | +| stake_to_reward | [int64](#int64) | | The sum of balances of all accounts staked to this node, considering only accounts that choose to receive rewards. | +| stake_to_not_reward | [int64](#int64) | | The sum of balances of all accounts staked to this node, considering only accounts that decline to receive rewards. | +| stake_reward_start | [int64](#int64) | | The snapshot of stake_to_reward value at the beginning of the current staking period.

This is necessary when calculating rewards for the current staking period without considering changes to `stake_to_reward` _within_ the current staking period.
This value SHALL be reset at the beginning of every staking period. | +| unclaimed_stake_reward_start | [int64](#int64) | | The amount of staked HBAR from `stake_reward_start` that will have unclaimed rewards due to accounts changing their staking metadata in a way that disqualifies them for the current staking period.

This value SHALL be reset at the beginning of every staking period. | +| stake | [int64](#int64) | | The total amount of HBAR staked to this node.

This is sum of stake_to_reward and stake_to_not_reward.
If the sum is greater than `max_stake`, then the _effective_ stake SHALL be `max_stake`.
If the sum is less than `min_stake`, then the _effective_ stake SHALL be `0`. | +| reward_sum_history | [int64](#int64) | repeated | A running list of reward amounts for the last 365+1 staking periods (typically a year and a day).

The first element SHALL be the reward up to and including the last full period prior to the present reward period.
The second element SHALL be the reward up to and including the period before the last full period prior to the present period.
The list SHALL continue in reverse chronological order until the reward history limit is reached. | +| weight | [int32](#int32) | | The consensus weight of this node in the network.

This is recomputed based on the `stake` of this node at midnight UTC of each day. If the `stake` of this node at that time is less than `min_stake`, then the weight SHALL be 0.
The sum of all weights of nodes in the network SHALL be less than 500.

Given the following:

The actual consensus weight for this node SHALL be calculated as __(500 * (`effective stake`/`effective network stake`))__ | +| pending_rewards | [int64](#int64) | | The total staking rewards in tinybars that MAY be collected by all accounts staking to the current node after the end of this staking period.

This SHALL be calculated assuming that no account "renounces" its rewards by setting `decline_reward` to true, or is ineligible for some other reason.
When the current node is deleted, this amount SHALL be subtracted from the total pending rewards of all accounts staking to all nodes in the network in NetworkStakingRewards. | +| deleted | [bool](#bool) | | A flag indicating that this node has been removed from this network. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/state/token/token.md b/documents/api/services/state/token/token.md new file mode 100644 index 00000000..cdd33577 --- /dev/null +++ b/documents/api/services/state/token/token.md @@ -0,0 +1,78 @@ +## Table of Contents + +- [state/token/token.proto](#state_token_token-proto) + - [Token](#proto-Token) + + + + + +

Top

+ +## state/token/token.proto +## Token +Tokens represent both fungible and non-fungible units of exchange. +The `Token` here represents a token within the network state. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in [RFC2119](https://www.ietf.org/rfc/rfc2119) +and clarified in [RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### Token +An Hedera Token Service(HTS) token. + +A token SHALL represent a fungible or non-fungible unit of exchange.
+The specified Treasury Account SHALL receive the initial supply of tokens and +SHALL determine distribution of all tokens once minted. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| token_id | [TokenID](#proto-TokenID) | | A unique identifier for this token. | +| name | [string](#string) | | A human-readable name for this token.

This value MAY NOT be unique.
This value SHALL NOT exceed 100 bytes when encoded as UTF-8. | +| symbol | [string](#string) | | A human-readable symbol for the token.

This value SHALL NOT be unique.
This value SHALL NOT exceed 100 bytes when encoded as UTF-8. | +| decimals | [int32](#int32) | | A number of decimal places for this token.

If decimals are 8 or 11, then the number of whole tokens can be at most billions or millions, respectively. More decimals allows for a more finely-divided token, but also limits the maximum total supply.

Examples

All token amounts in the network are stored as integer amounts, with each unit representing 10-decimals whole tokens.

For tokens with `token_type` set to `NON_FUNGIBLE_UNIQUE` this MUST be 0. | +| total_supply | [int64](#int64) | | A _current_ total supply of this token, expressed in the smallest unit of the token.

The number of _whole_ tokens this represents is (total_supply / 10decimals). The value of total supply, MUST be within the positive range of a twos-compliment signed 64-bit integer. The `total_supply`, therefore MUST be between 1, and 9,223,372,036,854,775,807, inclusive.

This value SHALL be reduced when a `token_burn` or `token_wipe_account` operation is executed, and SHALL be increased when a `token_mint` operation is executed. | +| treasury_account_id | [AccountID](#proto-AccountID) | | A treasury account identifier for this token.

When the token is created, the initial supply given in the token create transaction SHALL be minted and deposited in the treasury account.
All token mint transactions for this token SHALL deposit the new minted tokens in the treasury account.
All token burn transactions for this token SHALL remove the tokens to be burned from the treasury account. | +| admin_key | [Key](#proto-Key) | | Access control for general modification of this token.

This key MUST sign any `token_update` transaction that changes any attribute of the token other than expiration_time. Other attributes of this token MAY be changed by transactions other than `token_update`, and MUST be signed by one of the other purpose-specific keys assigned to the token.
This value can be set during token creation, and SHALL NOT be modified thereafter, unless the update transaction is signed by both the existing `admin_key` and the new `admin_key`.
If the `admin_key` is not set for a token, that token SHALL be immutable. | +| kyc_key | [Key](#proto-Key) | | Access control for KYC for this token.

Know Your Customer (KYC) status may be granted for an account by a token grant kyc transaction signed by this key.
If this key is not set, then KYC status cannot be granted to an account for this token, and any `TokenGrantKyc` transaction attempting to grant kyc to an account for this token SHALL NOT succeed.
This key MAY be set when the token is created, and MAY be set or modified via a token update transaction signed by the `admin_key`.
If `admin_key` is not set, this value, whether set or unset, SHALL be immutable. | +| freeze_key | [Key](#proto-Key) | | Access control to freeze this token.

A token may be frozen for an account, preventing any transaction from transferring that token for that specified account, by a token freeze account transaction signed by this key.
If this key is not set, the token cannot be frozen, and any transaction attempting to freeze the token for an account SHALL NOT succeed.
This key MAY be set when the token is created, and MAY be set or modified via a token update transaction signed by the `admin_key`.
If `admin_key` is not set, this value, whether set or unset, SHALL be immutable. | +| wipe_key | [Key](#proto-Key) | | Access control of account wipe for this token.

A token may be wiped, removing and burning tokens from a specific account, by a token wipe transaction, which MUST be signed by this key. The `treasury_account` cannot be subjected to a token wipe. A token burn transaction, signed by the `supply_key`, serves to burn tokens held by the `treasury_account` instead.
If this key is not set, the token cannot be wiped, and any transaction attempting to wipe the token from an account SHALL NOT succeed.
This key MAY be set when the token is created, and MAY be set or modified via a token update transaction signed by the `admin_key`.
If `admin_key` is not set, this value, whether set or unset, SHALL be immutable. | +| supply_key | [Key](#proto-Key) | | Access control of token mint/burn for this token.

A token mint transaction MUST be signed by this key, and any token mint transaction not signed by the current `supply_key` for that token SHALL NOT succeed.
A token burn transaction MUST be signed by this key, and any token burn transaction not signed by the current `supply_key` for that token SHALL NOT succeed.
This key MAY be set when the token is created, and MAY be set or modified via a token update transaction signed by the `admin_key`.
If `admin_key` is not set, this value, whether set or unset, SHALL be immutable. | +| fee_schedule_key | [Key](#proto-Key) | | Access control of the `custom_fees` field for this token.

The token custom fee schedule may be changed, modifying the fees charged for transferring that token, by a token update transaction, which MUST be signed by this key.
If this key is not set, the token custom fee schedule cannot be changed, and any transaction attempting to change the custom fee schedule for this token SHALL NOT succeed.
This key MAY be set when the token is created, and MAY be set or modified via a token update transaction signed by the `admin_key`.
If `admin_key` is not set, this value, whether set or unset, SHALL be immutable. | +| pause_key | [Key](#proto-Key) | | Access control of pause/unpause for this token.

A token may be paused, preventing any transaction from transferring that token, by a token update transaction signed by this key.
If this key is not set, the token cannot be paused, and any transaction attempting to pause the token SHALL NOT succeed.
This key MAY be set when the token is created, and MAY be set or modified via a token update transaction signed by the `admin_key`.
If `admin_key` is not set, this value, whether set or unset, SHALL be immutable. | +| last_used_serial_number | [int64](#int64) | | A last used serial number for this token.

This SHALL apply only to non-fungible tokens.
When a new NFT is minted, the serial number to apply SHALL be calculated from this value. | +| deleted | [bool](#bool) | | A flag indicating that this token is deleted.

A transaction involving a deleted token MUST NOT succeed. | +| token_type | [TokenType](#proto-TokenType) | | A type for this token.

A token SHALL be either `FUNGIBLE_COMMON` or `NON_FUNGIBLE_UNIQUE`.
If this value was omitted during token creation, `FUNGIBLE_COMMON` SHALL be used. | +| supply_type | [TokenSupplyType](#proto-TokenSupplyType) | | A supply type for this token.

A token SHALL have either `INFINITE` or `FINITE` supply type.
If this value was omitted during token creation, the value `INFINITE` SHALL be used. | +| auto_renew_account_id | [AccountID](#proto-AccountID) | | An identifier for the account (if any) that the network will attempt to charge for this token's auto-renewal upon expiration.

This field is OPTIONAL. If it is not set then renewal fees SHALL be charged to the account identified by `treasury_account_id`. | +| auto_renew_seconds | [int64](#int64) | | A number of seconds by which the network should automatically extend this token's expiration.

If the token has a valid auto-renew account, and is not deleted upon expiration, the network SHALL attempt to automatically renew this token.
If this is not provided in an allowed range on token creation, the transaction SHALL fail with `INVALID_AUTO_RENEWAL_PERIOD`.
The default values for the minimum period and maximum period are 30 days and 90 days, respectively. | +| expiration_second | [int64](#int64) | | An expiration time for this token, in seconds since the epoch.

For this purpose, `epoch` SHALL be the UNIX epoch with 0 at `1970-01-01T00:00:00.000Z`. | +| memo | [string](#string) | | A short description of this token.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8. | +| max_supply | [int64](#int64) | | A maximum supply of this token.
This is the maximum number of tokens of this type that may be issued.

This limit SHALL apply regardless of `token_type`.
If `supply_type` is `INFINITE` then this value MUST be 0.
If `supply_type` is `FINITE`, then this value MUST be greater than 0. | +| paused | [bool](#bool) | | A flag indicating that this token is paused.

A transaction involving a paused token, other than token_unpause, MUST NOT succeed. | +| accounts_frozen_by_default | [bool](#bool) | | A flag indicating that accounts associated to this token are frozen by default.

Accounts newly associated with this token CANNOT transact in the token until unfrozen.
This SHALL NOT prevent a `tokenReject` transaction to return the tokens from an account to the treasury account. | +| accounts_kyc_granted_by_default | [bool](#bool) | | A flag indicating that accounts associated with this token are granted KYC by default. | +| custom_fees | [CustomFee](#proto-CustomFee) | repeated | A custom fee schedule for this token. | +| metadata | [bytes](#bytes) | | A Token "Metadata".

This value, if set, SHALL NOT exceed 100 bytes. | +| metadata_key | [Key](#proto-Key) | | Access Control of metadata update for this token.

A transaction to update the `metadata` field of this token MUST be signed by this key.
If this token is a non-fungible/unique token type, a transaction to update the `metadata` field of any individual serialized unique token of this type MUST be signed by this key.
If this key is not set, the token metadata SHALL NOT be changed after it is created.
If this key is not set, the metadata for any individual serialized token of this type SHALL NOT be changed after it is created.
This key MAY be set when the token is created, and MAY be set or modified via a token update transaction signed by the `admin_key`.
If `admin_key` is not set, this value, whether set or unset, SHALL be immutable. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/state/token/token_relation.md b/documents/api/services/state/token/token_relation.md new file mode 100644 index 00000000..e23f67e0 --- /dev/null +++ b/documents/api/services/state/token/token_relation.md @@ -0,0 +1,69 @@ +## Table of Contents + +- [state/token/token_relation.proto](#state_token_token_relation-proto) + - [TokenRelation](#proto-TokenRelation) + + + + + +

Top

+ +## state/token/token_relation.proto +# Token Relationship. +This is a connection between one Account, one _fungible_ Token, and +associated balance within the Hedera network. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in [RFC2119](https://www.ietf.org/rfc/rfc2119) +and clarified in [RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### TokenRelation +An Hedera Token Service token relationship. + +A token relationship connects an Account with a Token and is necessary for +that Account to transact in that Token. TokenRelationship defines a +connection between one account and one token type. + +A TokenRelation SHALL be identified by the combination of token_id and +account_id.
+A TokenRelation SHALL contain, for the referenced token,
+The account's current balance, whether the account has KYC granted, +and whether the assets are frozen. + +TokenRelation entries SHALL be connected via a "virtual linked list" with the +next TokenID and previous TokenID stored in the TokenRelation. +These TokenIDs MUST be combined with the AccountID to find the next or +previous relationship in the list. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| token_id | [TokenID](#proto-TokenID) | | A token identifier.

This SHALL identify the token involved in this association. | +| account_id | [AccountID](#proto-AccountID) | | An account identifier.

This SHALL identify the account involved in this association. | +| balance | [int64](#int64) | | The fungible token balance of this token relationship.

This MUST be a whole number. | +| frozen | [bool](#bool) | | A flag indicating that this token relationship is frozen.

When a token relationship is frozen the associated account SHALL NOT be permitted to transfer to or from the associated balance.

This flag is associated with the Token value `freeze_key`, and any transaction to set this flag MUST be signed by that key. If the Token does not have a `freeze_key` set, then this flag SHALL NOT be set true for relationships between accounts and that token. | +| kyc_granted | [bool](#bool) | | A flag indicating that this token relationship has been granted KYC status.

If the token flag `accounts_kyc_granted_by_default` is set true, then this flag SHALL be set true for all accounts subsequently associated to that token. Otherwise this flag SHALL NOT be set until a transaction is submitted, and signed with the Token `kyc_key` to set the flag true.
If the Token does not have a `kyc_key` set and the token flag `accounts_kyc_granted_by_default` is not set true, then this value MUST be false for all accounts subsequently associated to that token.

Typically a transaction to set this value to true is considered equivalent to asserting that the "Know Your Customer" (KYC) requirements have been met for this combination of account and token and the relevant records are available as required. | +| automatic_association | [bool](#bool) | | A flag indicating that this token relationship was created using automatic association.

If this is true then there MUST NOT exist a customer-signed transaction associating this account and token combination and the account `used_auto_associations` SHALL be incremented when this relationship is created. | +| previous_token | [TokenID](#proto-TokenID) | | The Token ID of the previous entry in the associated Account's "virtual double-linked list" of token relationships.

This must be combined with the value of `account_id` to identify the actual `TokenRelation` referenced. | +| next_token | [TokenID](#proto-TokenID) | | The Token ID of the next entry in the associated Account's "virtual double-linked list" of token relationships.

This must be combined with the value of `account_id` to identify the actual `TokenRelation` referenced. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/system_delete.md b/documents/api/services/system_delete.md new file mode 100644 index 00000000..de52ccf4 --- /dev/null +++ b/documents/api/services/system_delete.md @@ -0,0 +1,72 @@ +## Table of Contents + +- [system_delete.proto](#system_delete-proto) + - [SystemDeleteTransactionBody](#proto-SystemDeleteTransactionBody) + + + + + +

Top

+ +## system_delete.proto +# System Delete +A system transaction to remove a file from the Hedera File +Service (HFS).
+This transaction is a privileged operation restricted to "system" +accounts. + +> Note +>> System delete is defined here for a smart contract (to delete +>> the bytecode), but was never implemented. +> +>> Currently, system delete and system undelete specifying a smart +>> contract identifier SHALL return `INVALID_FILE_ID` +>> or `MISSING_ENTITY_ID`. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### SystemDeleteTransactionBody +Delete a file or contract bytecode as an administrative transaction. + +> Note +>> A system delete/undelete for a `contractID` is not supported and +>> SHALL return `INVALID_FILE_ID` or `MISSING_ENTITY_ID`. + +This transaction MAY be reversed by the `systemUndelete` transaction. +A file deleted via `fileDelete`, however SHALL be irrecoverable.
+This transaction MUST specify an expiration timestamp (with seconds +precision). The file SHALL be permanently removed from state when +network consensus time exceeds the specified expiration time.
+This transaction MUST be signed by an Hedera administrative ("system") +account. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| fileID | [FileID](#proto-FileID) | | A file identifier.

The identified file MUST exist in the HFS.
The identified file MUST NOT be deleted.
This field is REQUIRED. | +| contractID | [ContractID](#proto-ContractID) | | A contract identifier.

The identified contract MUST exist in network state.
The identified contract bytecode MUST NOT be deleted.

This option is _unsupported_. | +| expirationTime | [TimestampSeconds](#proto-TimestampSeconds) | | A timestamp indicating when the file will be removed from state.

This value SHALL be expressed in seconds since the `epoch`. The `epoch` SHALL be the UNIX epoch with 0 at `1970-01-01T00:00:00.000Z`.
This field is REQUIRED. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/system_undelete.md b/documents/api/services/system_undelete.md new file mode 100644 index 00000000..358271e8 --- /dev/null +++ b/documents/api/services/system_undelete.md @@ -0,0 +1,68 @@ +## Table of Contents + +- [system_undelete.proto](#system_undelete-proto) + - [SystemUndeleteTransactionBody](#proto-SystemUndeleteTransactionBody) + + + + + +

Top

+ +## system_undelete.proto +# System Undelete +A system transaction to "undo" a `systemDelete` transaction.
+This transaction is a privileged operation restricted to "system" +accounts. + +> Note +>> System undelete is defined here for a smart contract (to delete +>> the bytecode), but was never implemented. +> +>> Currently, system delete and system undelete specifying a smart +>> contract identifier SHALL return `INVALID_FILE_ID` +>> or `MISSING_ENTITY_ID`. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### SystemUndeleteTransactionBody +Recover a file or contract bytecode deleted from the Hedera File +System (HFS) by a `systemDelete` transaction. + +> Note +>> A system delete/undelete for a `contractID` is not supported and +>> SHALL return `INVALID_FILE_ID` or `MISSING_ENTITY_ID`. + +This transaction can _only_ recover a file removed with the `systemDelete` +transaction. A file deleted via `fileDelete` SHALL be irrecoverable.
+This transaction MUST be signed by an Hedera administrative ("system") +account. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| fileID | [FileID](#proto-FileID) | | A file identifier.

The identified file MUST exist in the HFS.
The identified file MUST be deleted.
The identified file deletion MUST be a result of a `systemDelete` transaction.
This field is REQUIRED. | +| contractID | [ContractID](#proto-ContractID) | | A contract identifier.

The identified contract MUST exist in network state.
The identified contract bytecode MUST be deleted.
The identified contract deletion MUST be a result of a `systemDelete` transaction.

This option is _unsupported_. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/throttle_definitions.md b/documents/api/services/throttle_definitions.md new file mode 100644 index 00000000..67b14386 --- /dev/null +++ b/documents/api/services/throttle_definitions.md @@ -0,0 +1,120 @@ +## Table of Contents + +- [throttle_definitions.proto](#throttle_definitions-proto) + - [ThrottleBucket](#proto-ThrottleBucket) + - [ThrottleDefinitions](#proto-ThrottleDefinitions) + - [ThrottleGroup](#proto-ThrottleGroup) + + + + + +

Top

+ +## throttle_definitions.proto +# Throttle Definitions +A set of messages that support maintaining throttling limits on network +transactions to ensure no one transaction type consumes the entirety of +network resources. Also used to charge congestion fees when network load +is exceptionally high, as an incentive to delay transactions that are +not time-sensitive. + +For details behind this throttling design, please see the +`docs/throttle-design.md` document in the +[Hedera Services](https://github.com/hashgraph/hedera-services) repository. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### ThrottleBucket +A "bucket" of performance allocated across one or more throttle groups.
+This entry combines one or more throttle groups into a single unit to +calculate limitations and congestion. Each "bucket" "fills" as operations +are completed, then "drains" over a period of time defined for each bucket. +This fill-and-drain characteristic enables the network to process sudden +bursts of heavy traffic while still observing throttle limits over longer +timeframes. + +The value of `burstPeriodMs` is combined with the `milliOpsPerSec` +values for the individual throttle groups to determine the total +bucket "capacity". This combination MUST be less than the maximum +value of a signed long integer (`9223372036854775807`), when scaled to +a nanosecond measurement resolution. + +> Note +>> There is some question regarding the mechanism of calculating the +>> combination of `burstPeriodMs` and `milliOpsPerSec`. The calculation +>> Is implemented in difficult-to-find code, and very likely does not +>> match the approach described here. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| name | [string](#string) | | A name for this bucket.
This is used for log entries.

This value SHOULD NOT exceed 20 characters. | +| burstPeriodMs | [uint64](#uint64) | | A burst duration limit, in milliseconds.
This value determines the total "capacity" of the bucket. The rate at which the bucket "drains" is set by the throttles, and this duration sets how long that rate must be sustained to empty a "full" bucket. That combination (calculated as the product of this value and the least common multiple of the `milliOpsPerSec` values for all throttle groups) determines the maximum amount of operations this bucket can "hold".

The calculated capacity of this bucket MUST NOT exceed `9,223,372,036,854`. | +| throttleGroups | [ThrottleGroup](#proto-ThrottleGroup) | repeated | A list of throttle groups.
These throttle groups combined define the effective throttle rate for the bucket.

This list MUST contain at least one entry. | + + + + + + + + +### ThrottleDefinitions +A list of throttle buckets.
+This list, simultaneously enforced, defines a complete throttling policy. + + 1. When an operation appears in more than one throttling bucket, + that operation SHALL be throttled unless all of the buckets where + the operation appears have "capacity" available. + 1. An operation assigned to no buckets is SHALL be throttled in every + instance. The _effective_ throttle for this case is `0`. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| throttleBuckets | [ThrottleBucket](#proto-ThrottleBucket) | repeated | A list of throttle buckets.

This list MUST be set, and SHOULD NOT be empty.
An empty list SHALL have the effect of setting all operations to a single group with throttle limit of `0` operations per second for the entire network. | + + + + + + + + +### ThrottleGroup +A single throttle limit applied to one or more operations. + +The list of operations MUST contain at least one entry.
+The throttle limit SHALL be specified in thousandths of an operation +per second; one operation per second for the network would be `1000`.
+The throttle limit MUST be greater than zero (`0`). + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| operations | [HederaFunctionality](#proto-HederaFunctionality) | repeated | A list of operations to be throttled.

This list MUST contain at least one item.
This list SHOULD NOT contain any item included in any other active `ThrottleGroup`. | +| milliOpsPerSec | [uint64](#uint64) | | A throttle limit for this group.
This is a total number of operations, in thousandths, the network may perform each second for this group. Every node executes every transaction, so this limit effectively applies individually to each node as well.

This value MUST be greater than zero (`0`).
This value SHOULD be less than `9,223,372`.
| + + + + + + + + + + + + + + + diff --git a/documents/api/services/timestamp.md b/documents/api/services/timestamp.md new file mode 100644 index 00000000..4175fb23 --- /dev/null +++ b/documents/api/services/timestamp.md @@ -0,0 +1,70 @@ +## Table of Contents + +- [timestamp.proto](#timestamp-proto) + - [Timestamp](#proto-Timestamp) + - [TimestampSeconds](#proto-TimestampSeconds) + + + + + +

Top

+ +## timestamp.proto +# Timestamp +Messages to describe exact date-time values, with resolution of seconds or +nanoseconds, referenced to the UNIX epoch. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### Timestamp +An exact date and time.
+This is the same data structure as the Google protobuf Timestamp.proto. + +#### Additional Notes +Useful information is present in comments on the +[Google version](https://github.com/google/protobuf/blob/master/src/google/protobuf/timestamp.proto). + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| seconds | [int64](#int64) | | The number of complete seconds since the start of the epoch.

For this purpose, `epoch` SHALL be the UNIX epoch with 0 at `1970-01-01T00:00:00.000Z`.
This value MUST be greater than 0.
This value SHOULD be strictly greater than `946684800`. | +| nanos | [int32](#int32) | | The number of nanoseconds after the start of the second referenced in `seconds`.

This value MUST be greater than or equal to 0.
This value MUST be strictly less than 1,000,000,000. | + + + + + + + + +### TimestampSeconds +An exact date and time, with a resolution of one second. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| seconds | [int64](#int64) | | The number of complete seconds since the start of the epoch.

For this purpose, `epoch` SHALL be the UNIX epoch with 0 at `1970-01-01T00:00:00.000Z`.
This value MUST be greater than 0.
This value SHOULD be strictly greater than `946684800`. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/token_airdrop.md b/documents/api/services/token_airdrop.md new file mode 100644 index 00000000..d1d0feff --- /dev/null +++ b/documents/api/services/token_airdrop.md @@ -0,0 +1,108 @@ +## Table of Contents + +- [token_airdrop.proto](#token_airdrop-proto) + - [TokenAirdropTransactionBody](#proto-TokenAirdropTransactionBody) + + + + + +

Top

+ +## token_airdrop.proto +# Token Airdrop +Messages used to implement a transaction to "airdrop" tokens.
+An "airdrop" is a distribution of tokens from a funding account +to one or more recipient accounts, ideally with no action required +by the recipient account(s). + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### TokenAirdropTransactionBody +Airdrop one or more tokens to one or more accounts. + +### Effects +This distributes tokens from the balance of one or more sending account(s) +to the balance of one or more recipient accounts. Accounts MAY receive the +tokens in one of four ways. + + - An account already associated to the token to be distributed SHALL + receive the airdropped tokens immediately to the recipient account + balance.
+ The fee for this transfer SHALL include the transfer, the airdrop fee, + and any custom fees. + - An account with available automatic association slots SHALL be + automatically associated to the token, and SHALL immediately receive + the airdropped tokens to the recipient account balance.
+ The fee for this transfer SHALL include the transfer, the association, + the cost to renew that association once, the airdrop fee, and + any custom fees. + - An account with "receiver signature required" set SHALL have a + "Pending Airdrop" created and must claim that airdrop with a + `claimAirdrop` transaction.
+ The fee for this transfer SHALL include the transfer, the association, + the cost to renew that association once, the airdrop fee, and + any custom fees.
+ If the pending airdrop is not claimed immediately, the `sender` SHALL + pay the cost to renew the token association, and the cost to maintain + the pending airdrop, until the pending airdrop is claimed or cancelled. + - An account with no available automatic association slots SHALL have a + "Pending Airdrop" created and must claim that airdrop with a + `claimAirdrop` transaction.
+ The fee for this transfer SHALL include the transfer, the association, + the cost to renew that association once, the airdrop fee, and any custom + fees.
+ If the pending airdrop is not claimed immediately, the `sender` SHALL + pay the cost to renew the token association, and the cost to maintain + the pending airdrop, until the pending airdrop is claimed or cancelled. + +If an airdrop would create a pending airdrop for a fungible/common token, +and a pending airdrop for the same sender, receiver, and token already +exists, the existing pending airdrop SHALL be updated to add the new +amount to the existing airdrop, rather than creating +a new pending airdrop.
+Any airdrop that completes immediately SHALL be irreversible. Any airdrop +that results in a "Pending Airdrop" MAY be canceled via a `cancelAirdrop` +transaction.
+All transfer fees (including custom fees and royalties), as well as the +rent cost for the first auto-renewal period for any automatic-association +slot occupied by the airdropped tokens, SHALL be charged to the account +paying for this transaction.
+ +### Record Stream Effects +- Each successful transfer SHALL be recorded in `token_transfer_list` + for the transaction record. +- Each successful transfer that consumes an automatic association slot + SHALL populate the `automatic_association` field for the record. +- Each pending transfer _created_ SHALL be added to the + `pending_airdrops` field for the record. +- Each pending transfer _updated_ SHALL be added to the + `pending_airdrops` field for the record. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| token_transfers | [TokenTransferList](#proto-TokenTransferList) | repeated | A list of token transfers representing one or more airdrops.

The sender for each transfer MUST have sufficient balance to complete the transfers.
All token transfers MUST successfully transfer tokens or create a pending airdrop for this transaction to succeed.
This list MUST contain between 1 and 10 transfers, inclusive.

Note that each transfer of fungible/common tokens requires both a debit and a credit, so each _fungible_ token transfer MUST have _balanced_ entries in the TokenTransferList for that transfer. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/token_associate.md b/documents/api/services/token_associate.md new file mode 100644 index 00000000..13210243 --- /dev/null +++ b/documents/api/services/token_associate.md @@ -0,0 +1,75 @@ +## Table of Contents + +- [token_associate.proto](#token_associate-proto) + - [TokenAssociateTransactionBody](#proto-TokenAssociateTransactionBody) + + + + + +

Top

+ +## token_associate.proto +# Token Associate +Transaction to associate an Hedera Token Service (HTS) token with an +account.
+Accounts cannot transact in a token (send or receive) until the account +and token are associated. + +> Note +>> An "airdrop" transaction MAY initiate sending tokens to an +>> unassociated account, but the transfer remains in a "pending" +>> state until the recipient executes a "claim" transaction +>> that both accepts the tokens and associates that account +>> with the token type. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### TokenAssociateTransactionBody +Associate an Hedera Token Service (HTS) token and an account. + +An association MUST exist between an account and a token before that +account may transfer or receive that token.
+If the identified account is not found, +the transaction SHALL return `INVALID_ACCOUNT_ID`.
+If the identified account has been deleted, +the transaction SHALL return `ACCOUNT_DELETED`.
+If any of the identified tokens is not found, +the transaction SHALL return `INVALID_TOKEN_REF`.
+If any of the identified tokens has been deleted, +the transaction SHALL return `TOKEN_WAS_DELETED`.
+If an association already exists for any of the identified tokens, +the transaction SHALL return `TOKEN_ALREADY_ASSOCIATED_TO_ACCOUNT`.
+The identified account MUST sign this transaction. + +### Record Stream Effects +??? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| account | [AccountID](#proto-AccountID) | | An account identifier.

The identified account SHALL be associated to each of the tokens identified in the `tokens` field.
This field is REQUIRED and MUST be a valid account identifier.
The identified account MUST exist in state.
The identified account MUST NOT be deleted.
The identified account MUST NOT be expired. | +| tokens | [TokenID](#proto-TokenID) | repeated | A list of token identifiers.

Each token identified in this list SHALL be separately associated with the account identified in the `account` field.
This list MUST NOT be empty. Each entry in this list MUST be a valid token identifier.
Each entry in this list MUST NOT be currently associated to the account identified in `account`.
Each entry in this list MUST NOT be expired.
Each entry in this list MUST NOT be deleted. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/token_burn.md b/documents/api/services/token_burn.md new file mode 100644 index 00000000..db812fc4 --- /dev/null +++ b/documents/api/services/token_burn.md @@ -0,0 +1,68 @@ +## Table of Contents + +- [token_burn.proto](#token_burn-proto) + - [TokenBurnTransactionBody](#proto-TokenBurnTransactionBody) + + + + + +

Top

+ +## token_burn.proto +# Token Burn +Permanently remove tokens from circulation, akin to how a fiat treasury +will physically burn worn out bank notes. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### TokenBurnTransactionBody +Burns tokens from the Token's treasury Account. + +The token MUST have a `supply_key` set and that key MUST NOT +be an empty `KeyList`.
+The token `supply_key` MUST sign this transaction.
+This operation SHALL decrease the total supply for the token type by +the number of tokens "burned".
+The total supply for the token type MUST NOT be reduced below zero (`0`) +by this transaction.
+The tokens to burn SHALL be deducted from the token treasury account.
+If the token is a fungible/common type, the amount MUST be specified.
+If the token is a non-fungible/unique type, the specific serial numbers +MUST be specified.
+The global batch size limit (`tokens.nfts.maxBatchSizeBurn`) SHALL set +the maximum number of individual NFT serial numbers permitted in a single +`tokenBurn` transaction. + +### Record Stream Effects +??? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| token | [TokenID](#proto-TokenID) | | A token identifier.

This SHALL identify the token type to "burn".
The identified token MUST exist, and MUST NOT be deleted. | +| amount | [uint64](#uint64) | | An amount to burn from the Treasury Account.

This is interpreted as an amount in the smallest possible denomination for the token (10-decimals whole tokens).
The balance for the token treasury account MUST contain sufficient tokens to complete this transaction with a non-negative balance.
If this value is equal to zero (`0`), the token SHOULD be a non-fungible/unique type.
If this value is non-zero, the token MUST be a fungible/common type. | +| serialNumbers | [int64](#int64) | repeated | A list of serial numbers to burn from the Treasury Account.

This list MUST NOT contain more entries than the current limit set by the network configuration value `tokens.nfts.maxBatchSizeBurn`.
The treasury account for the token MUST hold each unique token identified in this list.
If this list is not empty, the token MUST be a non-fungible/unique type.
If this list is empty, the token MUST be a fungible/common type. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/token_cancel_airdrop.md b/documents/api/services/token_cancel_airdrop.md new file mode 100644 index 00000000..58457d6f --- /dev/null +++ b/documents/api/services/token_cancel_airdrop.md @@ -0,0 +1,55 @@ +## Table of Contents + +- [token_cancel_airdrop.proto](#token_cancel_airdrop-proto) + - [TokenCancelAirdropTransactionBody](#proto-TokenCancelAirdropTransactionBody) + + + + + +

Top

+ +## token_cancel_airdrop.proto +# Token Cancel Airdrop +Messages used to implement a transaction to cancel a pending airdrop. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### TokenCancelAirdropTransactionBody +Token cancel airdrop
+Remove one or more pending airdrops from state on behalf of the +sender(s) for each airdrop. + +Each pending airdrop canceled SHALL be removed from state and +SHALL NOT be available to claim.
+Each cancellation SHALL be represented in the transaction body and +SHALL NOT be restated in the record file.
+All cancellations MUST succeed for this transaction to succeed. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| pending_airdrops | [PendingAirdropId](#proto-PendingAirdropId) | repeated | A list of one or more pending airdrop identifiers.
This list declares the set of pending airdrop entries that the client wishes to cancel; on success all listed pending airdrop entries will be removed.

This transaction MUST be signed by the account identified by a `sender_id` for each entry in this list.
This list MUST NOT have any duplicate entries.
This list MUST contain between 1 and 10 entries, inclusive. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/token_claim_airdrop.md b/documents/api/services/token_claim_airdrop.md new file mode 100644 index 00000000..02b9b6d5 --- /dev/null +++ b/documents/api/services/token_claim_airdrop.md @@ -0,0 +1,61 @@ +## Table of Contents + +- [token_claim_airdrop.proto](#token_claim_airdrop-proto) + - [TokenClaimAirdropTransactionBody](#proto-TokenClaimAirdropTransactionBody) + + + + + +

Top

+ +## token_claim_airdrop.proto +# Token Claim Airdrop +Messages used to implement a transaction to claim a pending airdrop. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### TokenClaimAirdropTransactionBody +Token claim airdrop
+Complete one or more pending transfers on behalf of the +recipient(s) for an airdrop. + +The sender MUST have sufficient balance to fulfill the airdrop at the +time of claim. If the sender does not have sufficient balance, the +claim SHALL fail.
+Each pending airdrop successfully claimed SHALL be removed from state and +SHALL NOT be available to claim again.
+Each claim SHALL be represented in the transaction body and +SHALL NOT be restated in the record file.
+All claims MUST succeed for this transaction to succeed. + +### Record Stream Effects +The completed transfers SHALL be present in the transfer list. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| pending_airdrops | [PendingAirdropId](#proto-PendingAirdropId) | repeated | A list of one or more pending airdrop identifiers.

This transaction MUST be signed by the account identified by the `receiver_id` for each entry in this list.
This list MUST contain between 1 and 10 entries, inclusive.
This list MUST NOT have any duplicate entries. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/token_create.md b/documents/api/services/token_create.md new file mode 100644 index 00000000..f8edfd7b --- /dev/null +++ b/documents/api/services/token_create.md @@ -0,0 +1,112 @@ +## Table of Contents + +- [token_create.proto](#token_create-proto) + - [TokenCreateTransactionBody](#proto-TokenCreateTransactionBody) + + + + + +

Top

+ +## token_create.proto +# Token Create +Create an Hedera Token Service (HTS) token. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### TokenCreateTransactionBody +Create an HTS token. + +#### Keys +Each token has several keys that, separately, control different functions +for that token. It is *_strongly_* recommended that each key assigned to +a token be unique, or disabled by assigning an empty `KeyList`. +Keys and purpose +- `adminKey` is a general access and may authorize a token update + transaction as well as _update the other keys_. Even the admin key + cannot authorize _adding_ a key that is not present, however.
+ The admin key may also delete the token entirely. +- `fee_schedule` may authorize updating the token custom fees. If this + key is not present, the custom fees for the token are fixed and immutable. +- `freeze` may authorize a token freeze or unfreeze transaction. + If this key is not present, accounts holding this token cannot have + their tokens frozen or unfrozen. +- `kyc` may authorize a token grant KYC or revoke KYC transaction. + If this key is not present, accounts holding this token cannot have + KYC status granted or revoked. +- `metadata` may authorize token update nfts transactions. + If this key is not present, the token metadata values for that + non-fungible/unique token _type_ will be immutable. +- `pause` may authorize a token pause or token unpause transaction. + If this key is not present, the token cannot be paused (preventing any + account from transacting in that token) or resumed. +- `supply` may authorize a token mint or burn transaction. + If this key is not present, the token cannot mint additional supply and + existing tokens cannot be "burned" from the treasury (but _might_ still be + "burned" from individual accounts, c.f. `wipeKey` and `tokenWipe`). +- `wipe` may authorize a token wipe account transaction. + If this key is not present, accounts holding this token cannot have + their balance or NFTs wiped (effectively burned). + +#### Requirements +If `tokenType` is fungible/common, the `initialSupply` MUST be strictly +greater than zero(`0`).
+If `tokenType` is non-fungible/unique, the `initialSupply` MUST +be zero(`0`).
+If `tokenSupplyType` is "infinite", the `maxSupply` MUST be zero(`0`).
+If `tokenSupplyType` is "finite", the `maxSupply` MUST be strictly +greater than zero(`0`).
+ +### Record Stream Effects +If the token is created, the Token Identifier SHALL be in the receipt.
+ + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| name | [string](#string) | | A name for the token.
This is generally the "full name" displayed in wallet software.

This field is REQUIRED.
This value MUST NOT exceed 100 bytes when encoded as UTF-8.
This value MUST NOT contain the Unicode NUL codepoint. | +| symbol | [string](#string) | | A symbol to use for the token.

This field is REQUIRED.
This value MUST NOT exceed 100 bytes when encoded as UTF-8.
This value MUST NOT contain the Unicode NUL codepoint. | +| decimals | [uint32](#uint32) | | A decimal precision of the token's smallest denomination.
Most values are described in terms of this smallest denomination, so the token initial supply, for instance, must be divided by 10decimals to get whole tokens.

This MUST be zero(`0`) for non-fungible/unique tokens. | +| initialSupply | [uint64](#uint64) | | An initial supply, in the smallest denomination for the token.

This amount SHALL be transferred to the treasury account as part of this transaction.
This amount MUST be specified in the smallest denomination for the token (i.e. 10-decimals whole tokens).
This MUST be zero(`0`) for a non-fungible/unique token. | +| treasury | [AccountID](#proto-AccountID) | | A treasury account identifier.

This field is REQUIRED.
The identified account SHALL be designated the "treasury" for the new token, and all tokens "minted" SHALL be delivered to that account, including the initial supply, if any.
The identified account MUST exist, MUST NOT be expired, and SHOULD have a non-zero HBAR balance.
The identified account SHALL be associated to the new token. | +| adminKey | [Key](#proto-Key) | | An Hedera key for token administration.

This key, if set, SHALL have administrative authority for this token and MAY authorize token update and/or token delete transactions.
If this key is not set, or is an empty `KeyList`, this token SHALL be immutable, except for expiration and renewal. | +| kycKey | [Key](#proto-Key) | | An Hedera key for managing account KYC.

This key, if set, SHALL have KYC authority for this token and MAY authorize transactions to grant or revoke KYC for accounts.
If this key is not set, or is an empty `KeyList`, KYC status for this token SHALL NOT be granted or revoked for any account.
If this key is removed after granting KYC, those grants SHALL remain and cannot be revoked. | +| freezeKey | [Key](#proto-Key) | | An Hedera key for managing asset "freeze".

This key, if set, SHALL have "freeze" authority for this token and MAY authorize transactions to freeze or unfreeze accounts with respect to this token.
If this key is not set, or is an empty `KeyList`, this token SHALL NOT be frozen or unfrozen for any account.
If this key is removed after freezing accounts, those accounts SHALL remain frozen and cannot be unfrozen. | +| wipeKey | [Key](#proto-Key) | | An Hedera key for wiping tokens from accounts.

This key, if set, SHALL have "wipe" authority for this token and MAY authorize transactions to "wipe" any amount of this token from any account, effectively burning the tokens "wiped".
If this key is not set, or is an empty `KeyList`, it SHALL NOT be possible to "wipe" this token from an account. | +| supplyKey | [Key](#proto-Key) | | An Hedera key for "minting" and "burning" tokens.

This key, if set, MAY authorize transactions to "mint" new tokens to be delivered to the token treasury or "burn" tokens held by the token treasury.
If this key is not set, or is an empty `KeyList`, it SHALL NOT be possible to change the supply of tokens and neither "mint" nor "burn" transactions SHALL be permitted. | +| freezeDefault | [bool](#bool) | | An initial Freeze status for accounts associated to this token.

If this value is set, an account MUST be the subject of a `tokenUnfreeze` transaction after associating to the token before that account can send or receive this token.
If this value is set, the `freezeKey` SHOULD be set.
If the `freezeKey` is not set, any account associated to this token while this value is set SHALL be permanently frozen.

REVIEW NOTE
Should we prevent setting this value true for tokens with no freeze key?
Should we set this value to false if a freeze key is removed?
| +| expiry | [Timestamp](#proto-Timestamp) | | An expiration timestamp.

If the `autoRenewAccount` and `autoRenewPeriod` fields are set, this value SHALL be replaced with the current consensus time extended by the `autoRenewPeriod` duration.
If this value is set and token expiration is enabled in network configuration, this token SHALL expire when consensus time exceeds this value, and MAY be subsequently removed from the network state.
If this value is not set, and the automatic renewal account is also not set, then this value SHALL default to the current consensus time extended by the "default" expiration period from network configuration. | +| autoRenewAccount | [AccountID](#proto-AccountID) | | An identifier for the account to be charged renewal fees at the token's expiry to extend the lifetime of the token.

If this value is set, the token lifetime SHALL be extended by the _smallest_ of the following:

If this account's HBAR balance is `0` when the token must be renewed, then the token SHALL be expired, and MAY be subsequently removed from state.
If this value is set, the referenced account MUST sign this transaction. | +| autoRenewPeriod | [Duration](#proto-Duration) | | A duration between token automatic renewals.
All entities in state may be charged "rent" occasionally (typically every 90 days) to prevent unnecessary growth of the ledger. This value sets the interval between such events for this token.

This value MUST be set.
This value MUST be greater than the configured MIN_AUTORENEW_PERIOD.
This value MUST be less than the configured MAX_AUTORENEW_PERIOD. | +| memo | [string](#string) | | A short description for this token.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8. | +| tokenType | [TokenType](#proto-TokenType) | | A type for this token, according to IWA classification.

If this value is not set, the token SHALL have the default type of fungible/common.
This field SHALL be immutable. | +| supplyType | [TokenSupplyType](#proto-TokenSupplyType) | | A supply type for this token, according to IWA classification.

If this value is not set, the token SHALL have the default supply type of "infinite" (which is, as a practical matter, (263-1)/10decimals).
This field SHALL be immutable. | +| maxSupply | [int64](#int64) | | A maximum supply for this token.

This SHALL be interpreted in terms of the smallest fractional unit for this token.
If `supplyType` is "infinite", this MUST be `0`.
This field SHALL be immutable. | +| fee_schedule_key | [Key](#proto-Key) | | An Hedera key for managing the token custom fee schedule.

This key, if set, MAY authorize transactions to modify the `custom_fees` for this token.
If this key is not set, or is an empty `KeyList`, the `custom_fees` for this token SHALL NOT be modified. | +| custom_fees | [CustomFee](#proto-CustomFee) | repeated | A list of custom fees representing a fee schedule.

This list MAY be empty, which SHALL mean that there are no custom fees for this token.
If this token is a non-fungible/unique type, the entries in this list MUST NOT declare a `fractional_fee`.
If this token is a fungible/common type, the entries in this list MUST NOT declare a `royalty_fee`.
Any token type MAY include entries that declare a `fixed_fee`. | +| pause_key | [Key](#proto-Key) | | An Hedera key for managing token "pause".

This key, if set, SHALL have "pause" authority for this token and MAY authorize transactions to pause or unpause this token.
If this key is not set, or is an empty `KeyList`, this token SHALL NOT be paused or unpaused.
If this key is removed while the token is paused, the token cannot be unpaused and SHALL remain paused. | +| metadata | [bytes](#bytes) | | Token "Metadata".

The value, if set, MUST NOT exceed 100 bytes.

Examples
hcs://1/0.0.4896575
ipfs://bafkreifd7tcjjuwxxf4qkaibkj62pj4mhfuud7plwrc3pfoygt55al6syi
| +| metadata_key | [Key](#proto-Key) | | An Hedera key for managing the token `metadata`.

This key, if set, MAY authorize transactions to modify the `metadata` for this token.
If this key is not set, or is an empty `KeyList`, the `metadata` for this token SHALL NOT be modified. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/token_delete.md b/documents/api/services/token_delete.md new file mode 100644 index 00000000..9b9ccc98 --- /dev/null +++ b/documents/api/services/token_delete.md @@ -0,0 +1,71 @@ +## Table of Contents + +- [token_delete.proto](#token_delete-proto) + - [TokenDeleteTransactionBody](#proto-TokenDeleteTransactionBody) + + + + + +

Top

+ +## token_delete.proto +# Token Delete +Delete an Hedera Token Service (HTS) token. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### TokenDeleteTransactionBody +Mark a token as deleted.
+A deleted token remains present in the network state, but is no longer +active, cannot be held in a balance, and all operations on that token +fail. A deleted token is removed from network state when it expires. + +#### Operations on a deleted token +All operations on a deleted token SHALL fail with a +status code `TOKEN_WAS_DELETED`.
+Any attempt to transfer a deleted token between accounts SHALL fail with +a status code `TOKEN_WAS_DELETED`. + +> QUESTIONS +>> What happens to existing balances/NFTs? +>> Are these removed; are they stuck on the accounts? +> +>> If balances/NFTs remain, can a `tokenReject` remove them? + +#### Requirements +The `admin_key` for the token MUST be set, and MUST +sign this transaction.
+If the `admin_key` for the token is not set, this transaction SHALL +fail with a status code `TOKEN_IS_IMMUTABlE`. + +### Record Stream Effects +??? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| token | [TokenID](#proto-TokenID) | | A token identifier.

This SHALL identify the token type to delete.
The identified token MUST exist, and MUST NOT be deleted. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/token_dissociate.md b/documents/api/services/token_dissociate.md new file mode 100644 index 00000000..33c3192d --- /dev/null +++ b/documents/api/services/token_dissociate.md @@ -0,0 +1,74 @@ +## Table of Contents + +- [token_dissociate.proto](#token_dissociate-proto) + - [TokenDissociateTransactionBody](#proto-TokenDissociateTransactionBody) + + + + + +

Top

+ +## token_dissociate.proto +# Token Dissociate +Remove association between an account and one or more Hedera Token +Service (HTS) tokens. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### TokenDissociateTransactionBody +Dissociate an account from one or more HTS tokens. + +If the identified account is not found, +the transaction SHALL return `INVALID_ACCOUNT_ID`.
+If the identified account has been deleted, +the transaction SHALL return `ACCOUNT_DELETED`.
+If any of the identified tokens is not found, +the transaction SHALL return `INVALID_TOKEN_REF`.
+If any of the identified tokens has been deleted, +the transaction SHALL return `TOKEN_WAS_DELETED`.
+If an association does not exist for any of the identified tokens, +the transaction SHALL return `TOKEN_NOT_ASSOCIATED_TO_ACCOUNT`.
+If the identified account has a nonzero balance for any of the identified +tokens, and that token is neither deleted nor expired, the +transaction SHALL return `TRANSACTION_REQUIRES_ZERO_TOKEN_BALANCES`.
+If one of the identified tokens is a fungible/common token that is expired, +the account MAY disassociate from that token, even if that token balance is +not zero for that account.
+If one of the identified tokens is a non-fungible/unique token that is +expired, the account MUST NOT disassociate if that account holds any +individual NFT of that token. In this situation the transaction SHALL +return `TRANSACTION_REQUIRED_ZERO_TOKEN_BALANCES`.
+The identified account MUST sign this transaction. + +### Record Stream Effects +??? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| account | [AccountID](#proto-AccountID) | | An account identifier.

The identified account SHALL be dissociated from each of the tokens identified in the `tokens` field. This field is REQUIRED and MUST be a valid account identifier.
The identified account MUST exist in state.
The identified account MUST NOT be deleted.
The identified account MUST NOT be expired. | +| tokens | [TokenID](#proto-TokenID) | repeated | A list of token identifiers.

Each token identified in this list SHALL be dissociated from the account identified in the `account` field.
This list MUST NOT be empty. Each entry in this list MUST be a valid token identifier.
Each entry in this list MUST be currently associated to the account identified in `account`.
Entries in this list MAY be expired, if the token type is fungible/common.
Each entry in this list MUST NOT be deleted. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/token_fee_schedule_update.md b/documents/api/services/token_fee_schedule_update.md new file mode 100644 index 00000000..3b329e0c --- /dev/null +++ b/documents/api/services/token_fee_schedule_update.md @@ -0,0 +1,62 @@ +## Table of Contents + +- [token_fee_schedule_update.proto](#token_fee_schedule_update-proto) + - [TokenFeeScheduleUpdateTransactionBody](#proto-TokenFeeScheduleUpdateTransactionBody) + + + + + +

Top

+ +## token_fee_schedule_update.proto +# Fee Schedule Update +Transaction to update the fee schedule for a token. A token creator may +wish to charge custom transaction fees for a token type, and if a +`fee_schedule_key` is assigned, this transaction enables adding, removing, +or updating those custom transaction fees. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### TokenFeeScheduleUpdateTransactionBody +Update the custom fee schedule for a token type. + +The token MUST have a `fee_schedule_key` set and that key MUST NOT +be an empty `KeyList`.
+The token `fee_schedule_key` MUST sign this transaction.
+The token MUST exist, MUST NOT be deleted, and MUST NOT be expired.
+ +If the custom_fees list is empty, clears the fee schedule or resolves to +CUSTOM_SCHEDULE_ALREADY_HAS_NO_FEES if the fee schedule was already empty. + +### Record Stream Effects +??? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| token_id | [TokenID](#proto-TokenID) | | A token identifier.

This SHALL identify the token type to modify with an updated custom fee schedule.
The identified token MUST exist, and MUST NOT be deleted. | +| custom_fees | [CustomFee](#proto-CustomFee) | repeated | A list of custom fees representing a fee schedule.

This list MAY be empty to remove custom fees from a token.
If the identified token is a non-fungible/unique type, the entries in this list MUST NOT declare a `fractional_fee`.
If the identified token is a fungible/common type, the entries in this list MUST NOT declare a `royalty_fee`.
Any token type MAY include entries that declare a `fixed_fee`. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/token_freeze_account.md b/documents/api/services/token_freeze_account.md new file mode 100644 index 00000000..805f062c --- /dev/null +++ b/documents/api/services/token_freeze_account.md @@ -0,0 +1,66 @@ +## Table of Contents + +- [token_freeze_account.proto](#token_freeze_account-proto) + - [TokenFreezeAccountTransactionBody](#proto-TokenFreezeAccountTransactionBody) + + + + + +

Top

+ +## token_freeze_account.proto +# Token Freeze Account +Freeze all tokens of an identified type for an identified account. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### TokenFreezeAccountTransactionBody +Block transfers of a token type for an account.
+This, effectively, freezes assets of one account with respect to +one token type. While frozen, that account cannot send or receive tokens +of the identified type. + +The token MUST have a `freeze_key` set and that key MUST NOT +be an empty `KeyList`.
+The token `freeze_key` MUST sign this transaction.
+The identified token MUST exist, MUST NOT be deleted, MUST NOT be paused, +and MUST NOT be expired.
+The identified account MUST exist, MUST NOT be deleted, and +MUST NOT be expired.
+If the identified account is already frozen with respect to the identified +token, the transaction SHALL succeed, but no change SHALL be made.
+An association between the identified account and the identified +token MUST exist. + +### Record Stream Effects +??? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| token | [TokenID](#proto-TokenID) | | A token identifier.

This SHALL identify the token type to "freeze".
The identified token MUST exist, MUST NOT be deleted, and MUST be associated to the identified account. | +| account | [AccountID](#proto-AccountID) | | An account identifier.

This shall identify the account to "freeze".
The identified account MUST exist, MUST NOT be deleted, MUST NOT be expired, and MUST be associated to the identified token.
The identified account SHOULD NOT be "frozen" with respect to the identified token. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/token_get_account_nft_infos.md b/documents/api/services/token_get_account_nft_infos.md new file mode 100644 index 00000000..49c26a65 --- /dev/null +++ b/documents/api/services/token_get_account_nft_infos.md @@ -0,0 +1,70 @@ +## Table of Contents + +- [token_get_account_nft_infos.proto](#token_get_account_nft_infos-proto) + - [TokenGetAccountNftInfosQuery](#proto-TokenGetAccountNftInfosQuery) + - [TokenGetAccountNftInfosResponse](#proto-TokenGetAccountNftInfosResponse) + + + + + +

Top

+ +## token_get_account_nft_infos.proto +# Get Account NFT Infos +Deprecated and permanently disabled + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### TokenGetAccountNftInfosQuery +Deleted and unsupported. + +This query is not implemented and any query of this type submitted +SHALL return a `NOT_SUPPORTED` response code. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.
This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither). | +| accountID | [AccountID](#proto-AccountID) | | The Account for which information is requested | +| start | [int64](#int64) | | Specifies the start index (inclusive) of the range of NFTs to query for. Value must be in the range [0; ownedNFTs-1] | +| end | [int64](#int64) | | Specifies the end index (exclusive) of the range of NFTs to query for. Value must be in the range (start; ownedNFTs] | + + + + + + + + +### TokenGetAccountNftInfosResponse +Deleted and unsupported. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| nfts | [TokenNftInfo](#proto-TokenNftInfo) | repeated | List of NFTs associated to the account | + + + + + + + + + + + + + + + diff --git a/documents/api/services/token_get_info.md b/documents/api/services/token_get_info.md new file mode 100644 index 00000000..31581172 --- /dev/null +++ b/documents/api/services/token_get_info.md @@ -0,0 +1,112 @@ +## Table of Contents + +- [token_get_info.proto](#token_get_info-proto) + - [TokenGetInfoQuery](#proto-TokenGetInfoQuery) + - [TokenGetInfoResponse](#proto-TokenGetInfoResponse) + - [TokenInfo](#proto-TokenInfo) + + + + + +

Top

+ +## token_get_info.proto +# Get Token Info +Query to retrieve information for a single token. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### TokenGetInfoQuery +Request information for a token. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.
This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither). | +| token | [TokenID](#proto-TokenID) | | A token identifier.

This SHALL identify the token to query.
The identified token MUST exist, and MUST NOT be deleted. | + + + + + + + + +### TokenGetInfoResponse +A response message for the `getTokenInfo` query. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| tokenInfo | [TokenInfo](#proto-TokenInfo) | | The information requested for the identified token. | + + + + + + + + +### TokenInfo +An Hedera Token Service(HTS) token. + +A token SHALL represent a fungible or non-fungible unit of exchange.
+The specified Treasury Account SHALL receive the initial supply of tokens and +SHALL determine distribution of all tokens once minted. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| tokenId | [TokenID](#proto-TokenID) | | A unique identifier for this token. | +| name | [string](#string) | | A human-readable name for this token.

This value MAY NOT be unique.
This value SHALL NOT exceed 100 bytes when encoded as UTF-8. | +| symbol | [string](#string) | | A human-readable symbol for the token.

This value SHALL NOT be unique.
This value SHALL NOT exceed 100 bytes when encoded as UTF-8. | +| decimals | [uint32](#uint32) | | A number of decimal places for this token.

If decimals are 8 or 11, then the number of whole tokens can be at most billions or millions, respectively. More decimals allows for a more finely-divided token, but also limits the maximum total supply.

Examples

All token amounts in the network are stored as integer amounts, with each unit representing 10-decimals whole tokens.

For tokens with `token_type` set to `NON_FUNGIBLE_UNIQUE` this MUST be 0. | +| totalSupply | [uint64](#uint64) | | A _current_ total supply of this token, expressed in the smallest unit of the token.

The number of _whole_ tokens this represents is (total_supply / 10decimals). The value of total supply, MUST be within the positive range of a twos-compliment signed 64-bit integer. The `total_supply`, therefore MUST be between 1, and 9,223,372,036,854,775,807, inclusive.

This value SHALL be reduced when a `token_burn` or `token_wipe_account` operation is executed, and SHALL be increased when a `token_mint` operation is executed. | +| treasury | [AccountID](#proto-AccountID) | | A treasury account identifier for this token.

When the token is created, the initial supply given in the token create transaction SHALL be minted and deposited in the treasury account.
All token mint transactions for this token SHALL deposit the new minted tokens in the treasury account.
All token burn transactions for this token SHALL remove the tokens to be burned from the treasury account. | +| adminKey | [Key](#proto-Key) | | Access control for general modification of this token.

This key MUST sign any `token_update` transaction that changes any attribute of the token other than expiration_time. Other attributes of this token MAY be changed by transactions other than `token_update`, and MUST be signed by one of the other purpose-specific keys assigned to the token.
This value can be set during token creation, and SHALL NOT be modified thereafter, unless the update transaction is signed by both the existing `admin_key` and the new `admin_key`.
If the `admin_key` is not set for a token, that token SHALL be immutable. | +| kycKey | [Key](#proto-Key) | | Access control for KYC for this token.

Know Your Customer (KYC) status may be granted for an account by a token grant kyc transaction signed by this key.
If this key is not set, then KYC status cannot be granted to an account for this token, and any `TokenGrantKyc` transaction attempting to grant kyc to an account for this token SHALL NOT succeed.
This key MAY be set when the token is created, and MAY be set or modified via a token update transaction signed by the `admin_key`.
If `admin_key` is not set, this value, whether set or unset, SHALL be immutable. | +| freezeKey | [Key](#proto-Key) | | Access control to freeze this token.

A token may be frozen for an account, preventing any transaction from transferring that token for that specified account, by a token freeze account transaction signed by this key.
If this key is not set, the token cannot be frozen, and any transaction attempting to freeze the token for an account SHALL NOT succeed.
This key MAY be set when the token is created, and MAY be set or modified via a token update transaction signed by the `admin_key`.
If `admin_key` is not set, this value, whether set or unset, SHALL be immutable. | +| wipeKey | [Key](#proto-Key) | | Access control of account wipe for this token.

A token may be wiped, removing and burning tokens from a specific account, by a token wipe transaction, which MUST be signed by this key. The `treasury_account` cannot be subjected to a token wipe. A token burn transaction, signed by the `supply_key`, serves to burn tokens held by the `treasury_account` instead.
If this key is not set, the token cannot be wiped, and any transaction attempting to wipe the token from an account SHALL NOT succeed.
This key MAY be set when the token is created, and MAY be set or modified via a token update transaction signed by the `admin_key`.
If `admin_key` is not set, this value, whether set or unset, SHALL be immutable. | +| supplyKey | [Key](#proto-Key) | | Access control of token mint/burn for this token.

A token mint transaction MUST be signed by this key, and any token mint transaction not signed by the current `supply_key` for that token SHALL NOT succeed.
A token burn transaction MUST be signed by this key, and any token burn transaction not signed by the current `supply_key` for that token SHALL NOT succeed.
This key MAY be set when the token is created, and MAY be set or modified via a token update transaction signed by the `admin_key`.
If `admin_key` is not set, this value, whether set or unset, SHALL be immutable. | +| defaultFreezeStatus | [TokenFreezeStatus](#proto-TokenFreezeStatus) | | A flag indicating if accounts associated to this token are frozen by default, not frozen, or freeze is not applicable.

Accounts frozen by default and newly associated with this token CANNOT transact in the token until unfrozen.
This SHALL NOT prevent a `tokenReject` transaction to return the tokens from an account to the treasury account. | +| defaultKycStatus | [TokenKycStatus](#proto-TokenKycStatus) | | A flag indicating if accounts associated with this token are granted KYC by default, revoked by default, or KYC is not applicable. | +| deleted | [bool](#bool) | | A flag indicating that this token is deleted.

A transaction involving a deleted token MUST NOT succeed. | +| autoRenewAccount | [AccountID](#proto-AccountID) | | An identifier for the account (if any) that the network will attempt to charge for this token's auto-renewal upon expiration.

This field is OPTIONAL. If it is not set then renewal fees SHALL be charged to the account identified by `treasury`. | +| autoRenewPeriod | [Duration](#proto-Duration) | | A duration by which the network should automatically extend this token's expiration.

If the token has a valid auto-renew account, and is not deleted upon expiration, the network SHALL attempt to automatically renew this token.
The default values for the minimum period and maximum period are 30 days and 90 days, respectively. | +| expiry | [Timestamp](#proto-Timestamp) | | An expiration time for this token, in seconds since the epoch.

For this purpose, `epoch` SHALL be the UNIX epoch with 0 at `1970-01-01T00:00:00.000Z`. | +| memo | [string](#string) | | A short description of this token.

This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8. | +| tokenType | [TokenType](#proto-TokenType) | | A type for this token.

A token SHALL be either `FUNGIBLE_COMMON` or `NON_FUNGIBLE_UNIQUE`.
If this value was omitted during token creation, `FUNGIBLE_COMMON` SHALL be used.
The value `FUNGIBLE_COMMON` SHALL represent a fungible/common token. The value `NON_FUNGIBLE_UNIQUE` SHALL represent a non-fungible/unique token. | +| supplyType | [TokenSupplyType](#proto-TokenSupplyType) | | A supply type for this token.

A token SHALL have either `INFINITE` or `FINITE` supply type.
If this value was omitted during token creation, the value `INFINITE` SHALL be used. | +| maxSupply | [int64](#int64) | | A maximum supply of this token.
This is the maximum number of tokens of this type that may be issued.

This limit SHALL apply regardless of `token_type`.
If `supply_type` is `INFINITE` then this value MUST be 0.
If `supply_type` is `FINITE`, then this value MUST be greater than 0. | +| fee_schedule_key | [Key](#proto-Key) | | Access control of the `custom_fees` field for this token.

The token custom fee schedule may be changed, modifying the fees charged for transferring that token, by a token update transaction, which MUST be signed by this key.
If this key is not set, the token custom fee schedule cannot be changed, and any transaction attempting to change the custom fee schedule for this token SHALL NOT succeed.
This key MAY be set when the token is created, and MAY be set or modified via a token update transaction signed by the `admin_key`.
If `admin_key` is not set, this value, whether set or unset, SHALL be immutable. | +| custom_fees | [CustomFee](#proto-CustomFee) | repeated | A custom fee schedule for this token. | +| pause_key | [Key](#proto-Key) | | Access control of pause/unpause for this token.

A token may be paused, preventing any transaction from transferring that token, by a token update transaction signed by this key.
If this key is not set, the token cannot be paused, and any transaction attempting to pause the token SHALL NOT succeed.
This key MAY be set when the token is created, and MAY be set or modified via a token update transaction signed by the `admin_key`.
If `admin_key` is not set, this value, whether set or unset, SHALL be immutable. | +| pause_status | [TokenPauseStatus](#proto-TokenPauseStatus) | | A flag indicating that this token is paused.
A token may be paused, unpaused, or pause not applicable.

A transaction involving a paused token, other than token_unpause, MUST NOT succeed. | +| ledger_id | [bytes](#bytes) | | The ledger ID of the network that generated this response.
This is originally defined in `HIP-198` and depends on network configuration.
The current values, as of Q1 2024, are

Mainnet
0x00
Testnet
0x01
Previewnet
0x02
Undefined
0x03
Reserved
0x04
| +| metadata | [bytes](#bytes) | | A Token "Metadata".

This value, if set, SHALL NOT exceed 100 bytes. | +| metadata_key | [Key](#proto-Key) | | Access Control of metadata update for this token.

A transaction to update the `metadata` field of this token MUST be signed by this key.
If this token is a non-fungible/unique token type, a transaction to update the `metadata` field of any individual serialized unique token of this type MUST be signed by this key.
If this key is not set, the token metadata SHALL NOT be changed after it is created.
If this key is not set, the metadata for any individual serialized token of this type SHALL NOT be changed after it is created.
This key MAY be set when the token is created, and MAY be set or modified via a token update transaction signed by the `admin_key`.
If `admin_key` is not set, this value, whether set or unset, SHALL be immutable. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/token_get_nft_info.md b/documents/api/services/token_get_nft_info.md new file mode 100644 index 00000000..b15fd56a --- /dev/null +++ b/documents/api/services/token_get_nft_info.md @@ -0,0 +1,86 @@ +## Table of Contents + +- [token_get_nft_info.proto](#token_get_nft_info-proto) + - [TokenGetNftInfoQuery](#proto-TokenGetNftInfoQuery) + - [TokenGetNftInfoResponse](#proto-TokenGetNftInfoResponse) + - [TokenNftInfo](#proto-TokenNftInfo) + + + + + +

Top

+ +## token_get_nft_info.proto +# + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### TokenGetNftInfoQuery +Applicable only to tokens of type NON_FUNGIBLE_UNIQUE. Gets info on a NFT for a given TokenID (of +type NON_FUNGIBLE_UNIQUE) and serial number + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.
This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither). | +| nftID | [NftID](#proto-NftID) | | A non-fungible/unique token (NFT) identifier.

This SHALL identify the NFT to query.
The identified NFT MUST exist, and MUST NOT be deleted. | + + + + + + + + +### TokenGetNftInfoResponse +UNDOCUMENTED + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| nft | [TokenNftInfo](#proto-TokenNftInfo) | | The information about this NFT | + + + + + + + + +### TokenNftInfo +Information for one non-fungible/unique token (NFT). + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| nftID | [NftID](#proto-NftID) | | A non-fungible/unique token (NFT) identifier.

This SHALL match the NFT requested.
| +| accountID | [AccountID](#proto-AccountID) | | The current owner of the NFT | +| creationTime | [Timestamp](#proto-Timestamp) | | The effective consensus timestamp at which the NFT was minted | +| metadata | [bytes](#bytes) | | Represents the unique metadata of the NFT | +| ledger_id | [bytes](#bytes) | | The ledger ID of the network that generated this response.
This is originally defined in `HIP-198` and depends on network configuration.
The current values, as of Q1 2024, are

Mainnet
0x00
Testnet
0x01
Previewnet
0x02
Undefined
0x03
Reserved
0x04
| +| spender_id | [AccountID](#proto-AccountID) | | If an allowance is granted for the NFT, its corresponding spender account | + + + + + + + + + + + + + + + diff --git a/documents/api/services/token_get_nft_infos.md b/documents/api/services/token_get_nft_infos.md new file mode 100644 index 00000000..b13561b4 --- /dev/null +++ b/documents/api/services/token_get_nft_infos.md @@ -0,0 +1,71 @@ +## Table of Contents + +- [token_get_nft_infos.proto](#token_get_nft_infos-proto) + - [TokenGetNftInfosQuery](#proto-TokenGetNftInfosQuery) + - [TokenGetNftInfosResponse](#proto-TokenGetNftInfosResponse) + + + + + +

Top

+ +## token_get_nft_infos.proto +# Token Get NFT Infos +Deprecated and permanently disabled + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### TokenGetNftInfosQuery +Deleted and unsupported. + +This query is not implemented and any query of this type submitted +SHALL return a `NOT_SUPPORTED` response code. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [QueryHeader](#proto-QueryHeader) | | Standard information sent with every query operation.
This includes the signed payment and what kind of response is requested (cost, state proof, both, or neither). | +| tokenID | [TokenID](#proto-TokenID) | | A token identifier.

This SHALL identify the token to query.
The identified token MUST exist, MUST NOT be deleted, and MUST be a non-fungible/unique type. | +| start | [int64](#int64) | | Specifies the start index (inclusive) of the range of NFTs to query for. Value must be in the range [0; mintedNFTs-1] | +| end | [int64](#int64) | | Specifies the end index (exclusive) of the range of NFTs to query for. Value must be in the range (start; mintedNFTs] | + + + + + + + + +### TokenGetNftInfosResponse +Deleted and unsupported. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| header | [ResponseHeader](#proto-ResponseHeader) | | The standard response information for queries.
This includes the values requested in the `QueryHeader` (cost, state proof, both, or neither). | +| tokenID | [TokenID](#proto-TokenID) | | A token identifier.

This SHALL identify the token type to query.
The identified token MUST exist, and MUST NOT be deleted. The identified token MUST be a non-fungible/unique type. | +| nfts | [TokenNftInfo](#proto-TokenNftInfo) | repeated | A list of messages, each of which describes one NFT. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/token_grant_kyc.md b/documents/api/services/token_grant_kyc.md new file mode 100644 index 00000000..1f1248d5 --- /dev/null +++ b/documents/api/services/token_grant_kyc.md @@ -0,0 +1,69 @@ +## Table of Contents + +- [token_grant_kyc.proto](#token_grant_kyc-proto) + - [TokenGrantKycTransactionBody](#proto-TokenGrantKycTransactionBody) + + + + + +

Top

+ +## token_grant_kyc.proto +# Token Grant KYC +Grant "KYC" status to an account with respect to a token. + +The "KYC' property is named for the "Know Your Customer" requirements in +US federal regulations (FINRA 2090 and related US Code) that was subsequently +incorporated into laws and regulations for many worldwide jurisdictions. +The process requires a regulated financial entity to positively identify +customers and certain other entities. + +This transaction enables a token administrator to track whether KYC +requirements are met for a given account transacting in that token. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### TokenGrantKycTransactionBody +Grant "Know Your Customer"(KYC) for one account for a single token. + +This transaction MUST be signed by the `kyc_key` for the token.
+The identified token MUST have a `kyc_key` set to a valid `Key` value.
+The token `kyc_key` MUST NOT be an empty `KeyList`.
+The identified token MUST exist and MUST NOT be deleted.
+The identified account MUST exist and MUST NOT be deleted.
+The identified account MUST have an association to the identified token.
+On success the association between the identified account and the identified +token SHALL be marked as "KYC granted". + +### Record Stream Effects +??? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| token | [TokenID](#proto-TokenID) | | A token identifier.

The identified token SHALL grant "KYC" for the account identified by the `account` field.
The identified token MUST be associated to the account identified by the `account` field. | +| account | [AccountID](#proto-AccountID) | | An account identifier.

The token identified by the `token` field SHALL grant "KYC" for the identified account.
This account MUST be associated to the token identified by the `token` field. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/token_mint.md b/documents/api/services/token_mint.md new file mode 100644 index 00000000..139ceccc --- /dev/null +++ b/documents/api/services/token_mint.md @@ -0,0 +1,70 @@ +## Table of Contents + +- [token_mint.proto](#token_mint-proto) + - [TokenMintTransactionBody](#proto-TokenMintTransactionBody) + + + + + +

Top

+ +## token_mint.proto +# Token Mint +Mint new tokens and deliver them to the token treasury. This is akin +to how a fiat treasury will mint new coinage for circulation. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### TokenMintTransactionBody +Mint tokens and deliver the new tokens to the token treasury account. + +The token MUST have a `supply_key` set and that key MUST NOT +be an empty `KeyList`.
+The token `supply_key` MUST sign this transaction.
+This operation SHALL increase the total supply for the token type by +the number of tokens "minted".
+The total supply for the token type MUST NOT be increased above the +maximum supply limit (2^63-1) by this transaction.
+The tokens minted SHALL be credited to the token treasury account.
+If the token is a fungible/common type, the amount MUST be specified.
+If the token is a non-fungible/unique type, the metadata bytes for each +unique token MUST be specified in the `metadata` list.
+Each unique metadata MUST not exceed the global metadata size limit defined +by the network configuration value `tokens.maxMetadataBytes`.
+The global batch size limit (`tokens.nfts.maxBatchSizeMint`) SHALL set +the maximum number of individual NFT metadata permitted in a single +`tokenMint` transaction. + +### Record Stream Effects +??? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| token | [TokenID](#proto-TokenID) | | A token identifier.

This SHALL identify the token type to "mint".
The identified token MUST exist, and MUST NOT be deleted. | +| amount | [uint64](#uint64) | | An amount to mint to the Treasury Account.

This is interpreted as an amount in the smallest possible denomination for the token (10-decimals whole tokens).
The balance for the token treasury account SHALL receive the newly minted tokens.
If this value is equal to zero (`0`), the token SHOULD be a non-fungible/unique type.
If this value is non-zero, the token MUST be a fungible/common type. | +| metadata | [bytes](#bytes) | repeated | A list of metadata bytes.

One non-fungible/unique token SHALL be minted for each entry in this list.
Each entry in this list MUST NOT be larger than the limit set by the current network configuration value `tokens.maxMetadataBytes`.
This list MUST NOT contain more entries than the current limit set by the network configuration value `tokens.nfts.maxBatchSizeMint`.
If this list is not empty, the token MUST be a non-fungible/unique type.
If this list is empty, the token MUST be a fungible/common type. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/token_pause.md b/documents/api/services/token_pause.md new file mode 100644 index 00000000..c25405d0 --- /dev/null +++ b/documents/api/services/token_pause.md @@ -0,0 +1,61 @@ +## Table of Contents + +- [token_pause.proto](#token_pause-proto) + - [TokenPauseTransactionBody](#proto-TokenPauseTransactionBody) + + + + + +

Top

+ +## token_pause.proto +# Token Pause +A transaction to "pause" all activity for a token. While a token is paused +it cannot be transferred between accounts by any transaction other than +`rejectToken`. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### TokenPauseTransactionBody +Pause transaction activity for a token. + +This transaction MUST be signed by the Token `pause_key`.
+The `token` identified MUST exist, and MUST NOT be deleted.
+The `token` identified MAY be paused; if the token is already paused, +this transaction SHALL have no effect. +The `token` identified MUST have a `pause_key` set, the `pause_key` MUST be +a valid `Key`, and the `pause_key` MUST NOT be an empty `KeyList`.
+A `paused` token SHALL NOT be transferred or otherwise modified except to +"up-pause" the token with `unpauseToken` or in a `rejectToken` transaction. + +### Record Stream Effects +??? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| token | [TokenID](#proto-TokenID) | | A token identifier.

The identified token SHALL be paused. Subsequent transactions involving that token SHALL fail until the token is "unpaused". | + + + + + + + + + + + + + + + diff --git a/documents/api/services/token_reject.md b/documents/api/services/token_reject.md new file mode 100644 index 00000000..03f04296 --- /dev/null +++ b/documents/api/services/token_reject.md @@ -0,0 +1,86 @@ +## Table of Contents + +- [token_reject.proto](#token_reject-proto) + - [TokenReference](#proto-TokenReference) + - [TokenRejectTransactionBody](#proto-TokenRejectTransactionBody) + + + + + +

Top

+ +## token_reject.proto +# Token Reject +Messages used to implement a transaction to reject a token type from an +account. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### TokenReference +A union token identifier. + +Identify a fungible/common token type, or a single +non-fungible/unique token serial. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| fungible_token | [TokenID](#proto-TokenID) | | A fungible/common token type. | +| nft | [NftID](#proto-NftID) | | A single specific serialized non-fungible/unique token. | + + + + + + + + +### TokenRejectTransactionBody +Reject undesired token(s).
+Transfer one or more token balances held by the requesting account to the +treasury for each token type. + +Each transfer SHALL be one of the following +- A single non-fungible/unique token. +- The full balance held for a fungible/common token. +A single `tokenReject` transaction SHALL support a maximum +of 10 transfers.
+A token that is `pause`d MUST NOT be rejected.
+If the `owner` account is `frozen` with respect to the identified token(s) +the token(s) MUST NOT be rejected.
+The `payer` for this transaction, and `owner` if set, SHALL NOT be charged +any custom fees or other fees beyond the `tokenReject` transaction fee. + +### Transaction Record Effects +- Each successful transfer from `payer` to `treasury` SHALL be recorded in + the `token_transfer_list` for the transaction record. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| owner | [AccountID](#proto-AccountID) | | An account identifier.
This OPTIONAL field identifies the account holding the tokens to be rejected.

If set, this account MUST sign this transaction. If not set, the `payer` for this transaction SHALL be the effective `owner` for this transaction. | +| rejections | [TokenReference](#proto-TokenReference) | repeated | A list of one or more token rejections.

On success each rejected token serial number or balance SHALL be transferred from the requesting account to the treasury account for that token type.
After rejection the requesting account SHALL continue to be associated with the token.
If dissociation is desired then a separate `TokenDissociate` transaction MUST be submitted to remove the association.
This list MUST contain at least one (1) entry and MUST NOT contain more than ten (10) entries. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/token_revoke_kyc.md b/documents/api/services/token_revoke_kyc.md new file mode 100644 index 00000000..1292f6ae --- /dev/null +++ b/documents/api/services/token_revoke_kyc.md @@ -0,0 +1,69 @@ +## Table of Contents + +- [token_revoke_kyc.proto](#token_revoke_kyc-proto) + - [TokenRevokeKycTransactionBody](#proto-TokenRevokeKycTransactionBody) + + + + + +

Top

+ +## token_revoke_kyc.proto +# Token Revoke KYC +Revoke "KYC" status from an account with respect to a token. + +The "KYC' property is named for the "Know Your Customer" requirements in +US federal regulations (FINRA 2090 and related US Code) that was subsequently +incorporated into laws and regulations for many worldwide jurisdictions. +The process requires a regulated financial entity to positively identify +customers and certain other entities. + +This transaction enables a token administrator to track whether KYC +requirements are met for a given account transacting in that token. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + +### TokenRevokeKycTransactionBody +Revoke "Know Your Customer"(KYC) from one account for a single token. + +This transaction MUST be signed by the `kyc_key` for the token.
+The identified token MUST have a `kyc_key` set to a valid `Key` value.
+The token `kyc_key` MUST NOT be an empty `KeyList`.
+The identified token MUST exist and MUST NOT be deleted.
+The identified account MUST exist and MUST NOT be deleted.
+The identified account MUST have an association to the identified token.
+On success the association between the identified account and the identified +token SHALL NOT be marked as "KYC granted". + +### Record Stream Effects +??? + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| token | [TokenID](#proto-TokenID) | | A token identifier.

The identified token SHALL revoke "KYC" for the account identified by the `account` field.
The identified token MUST be associated to the account identified by the `account` field. | +| account | [AccountID](#proto-AccountID) | | An account identifier.

The token identified by the `token` field SHALL revoke "KYC" for the identified account.
This account MUST be associated to the token identified by the `token` field. | + + + + + + + + + + + + + + + diff --git a/documents/api/services/token_service.md b/documents/api/services/token_service.md new file mode 100644 index 00000000..1d6842b6 --- /dev/null +++ b/documents/api/services/token_service.md @@ -0,0 +1,66 @@ +## Table of Contents + +- [token_service.proto](#token_service-proto) + - [TokenService](#proto-TokenService) + + + + + +

Top

+ +## token_service.proto +# Token Service +gRPC definitions for token service transactions. + +### Keywords +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in +[RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in +[RFC8174](https://www.ietf.org/rfc/rfc8174). + + + + + + + + + + +### TokenService +Transactions and queries for the Token Service + +The following queries are permanently removed +getAccountNftInfos, getTokenNftInfos + +| Method Name | Request Type | Response Type | Description | +| ----------- | ------------ | ------------- | ------------| +| createToken | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Create a new token. | +| updateToken | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Update a token. | +| mintToken | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Mint one or more tokens to the treasury account.

This MAY specify a quantity of fungible/common tokens or a list of specific non-fungible/unique tokes, but MUST NOT specify both. | +| burnToken | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Burn one or more tokens from the treasury account.

This MAY specify a quantity of fungible/common tokens or a list of specific non-fungible/unique tokes, but MUST NOT specify both. | +| deleteToken | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Delete a token. | +| wipeTokenAccount | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Wipe one or more tokens from an identified Account.

This MAY specify a quantity of fungible/common tokens or a list of specific non-fungible/unique tokes, but MUST NOT specify both. | +| freezeTokenAccount | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Freeze the transfer of tokens to or from an identified Account. | +| unfreezeTokenAccount | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Unfreeze the transfer of tokens to or from an identified Account. | +| grantKycToTokenAccount | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Assert that KYC requirements are met for a specific account with respect to a specific token. | +| revokeKycFromTokenAccount | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Assert that KYC requirements are _not_ met for a specific account with respect to a specific token. | +| associateTokens | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Associate one or more tokens to an account. | +| dissociateTokens | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Dissociate one or more tokens from an account. | +| updateTokenFeeSchedule | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Update the custom fee schedule for a token. | +| getTokenInfo | [Query](#proto-Query) | [Response](#proto-Response) | Retrieve the detail characteristics for a token.

This query SHALL return information for the token type as a whole.
This query SHALL NOT return information for individual tokens. | +| getTokenNftInfo | [Query](#proto-Query) | [Response](#proto-Response) | Retrieve the metadata for a specific non-fungible/unique token.
The NFT to query is identified by token identifier and serial number.

This query SHALL return token metadata and, if an allowance is defined, the designated "spender" account for the queried NFT. | +| pauseToken | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Pause a token. | +| unpauseToken | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Unpause (resume) a token. | +| updateNfts | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Update multiple non-fungible/unique tokens (NFTs) in a collection.
The NFTs are identified by token identifier and one or more serial numbers.

This transaction SHALL update NFT metadata only.
This transaction MUST be signed by the token `metadata_key`. | +| rejectToken | [Transaction](#proto-Transaction) | [TransactionResponse](#proto-TransactionResponse) | Reject one or more tokens.

This transaction SHALL transfer the full balance of one or more tokens from the requesting account to the treasury for each token.
This transfer SHALL NOT charge any custom fee or royalty defined for the token(s) to be rejected.

Effects on success