Options
All
  • Public
  • Public/Protected
  • All
Menu

The ContractEncoder class. Can encode transactions, resolve overloads, and wrap values. See below for a method listing.

Hierarchy

  • ContractEncoder

Index

Constructors

Properties

abi: Abi
artifact: ContractObject
compilation: Compilation
constructorBinary: string
constructorContextHash: string
contract: Contract
contractNode: AstNode
deployedContextHash: string
noBytecodeAllocations: {}

Type declaration

projectEncoder: ProjectEncoder

Methods

  • This method is asynchronous.

    This method is similar to encodeTransaction, except that instead of encoding a function transaction, it encodes a creation transaction.

    Because this method does not perform overload resolution, it only returns the resulting transaction options (including the encoded data), and does not bother returning the ABI used (as this was user-supplied.)

    If the allowOptions flag is set in the options argument, the input may contain an additional transaction options argument after the other arguments. Any non-data options not specified in such a transaction options argument will be simply omitted; it you want some options to have defaults, it is up to the you to set these options as appropriate afterwards.

    If the transaction options parameter has a data or a to option, these option will be recognized but ignored.

    See encodeTransaction for documentation of the inputs.

    Parameters

    Returns Promise<Options>

  • encodeTransaction(abisOrNameOrSig: string | FunctionEntry[], inputs: unknown[], options?: ResolveOptions): Promise<TxAndAbi>
  • This method is asynchronous.

    This method recognizes user input for a given set of contract methods, attempts to interpret it as valid input for one of them, and then encodes the result. (That is to say, it performs overload resolution, then encodes.) Note that this method cannot be used to encode contract creations; use encodeTxNoResolution for that.

    If this method cannot match the user input to any of the possible overloads, it will throw a TypeMismatchError or a NoOverloadsMatchedError. If more than one overload matches but none can be considered the unique best, you will get a NoUniqueBestOverloadError. If due to inputting a nonexistent function name there are no overloads to check, you will get a [[NoFunctionByThatNameError]]. See below for a full list of the accepted forms of input, and see resolveAndWrap for full documentation of the overload resolution system.

    Be aware that overload resolution may not always be fully reliable; if you want to be absolutely certain that you get the right overload, you can use encodeTxNoResolution, which does not perform overload resolution, but requires you to specify exactly which overload you mean. However, you can also adjust your input to this function to get the overload you want; see below about { type: ..., value: ... } input and enum string input for details.

    If the allowOptions flag is set in the options argument, the input may contain an additional transaction options argument after the other arguments. Any non-data options not specified in such a transaction options argument will be simply omitted; it you want some options to have defaults, it is up to the you to set these options as appropriate afterwards. Also, if the transaction options parameter has a data option, this option will be recognized but ignored.

    Use of the encoder for transactions to be sent to libraries is presently not supported and may have unreliable results. Limited support for this is planned for future versions.

    Accepted forms of input

    The input argument may come in a number of forms, depending on the target data type. A list of the specific inputs accepted for each type is below. However first we must note a few generic forms that inputs are accepted in.

    Inputs may be given as an object of the form { type: ..., value: ... } (additional fields not allowed), where type is a string describing the type, and value is anything that would be accepted for that type (other than another type/value object). This form of input is not very useful with this method, but it is useful when performing overload resolution (see resolveAndWrap) to restrict the overloads that will be selected from. Note that for arrays, type should simply be "array"; for structs and tuples, "struct" or "tuple"; for addresses and contracts, "address" or "contract"; for external functions, "function"; for transaction options, "options"; and for enums, it can be either "enum" (or the underlying uint type). For other Solidity types, it should be the name of the type; note that "uint", "int", "fixed", "ufixed", and "byte" are accepted. Vyper's "decimal" type is also accepted. Also, user-defined value types use exactly the same type field as the underlying type; this input format does not distinguish between them and the underlying type.

    Note that input in the form of a Value is accepted, so long as the type is appropriate, but error results are typically not accepted (exceptions are discussed below).

    Now then, the list of accepted inputs by type, excluding the above:

    Strings: The input may be given as string (or String); note that strings with invalid UTF-16 will not be accepted. It may also be given as a Uint8Array (or anything that mimics one; see below about bytestrings), which will be treated as UTF-8; note that invalid UTF-8 is allowed in this format. Strings may also be given as a StringValue.

    Integer types: Input for integer types may take a variety of forms. The input may be a number (or Number); note that if so it must be a safe integer. For larger integers, you must use other forms of input. For instance, the input may be a BigInt. The input may also be one of several recognized big number classes:

    • BN
    • Big
    • MikeMcl's BigNumber
    • Ethers's BigNumber or FixedNumber Of course, any numeric input, no matter the format, must be integral. Input may also take the form of a numeric string (or String). The string may be decimal, but it may also be hexadecimal with "0x" prefix, octal with "0o" prefix, or binary with "0xb" prefix. You can also use a negated hexadecimal, octal, or binary string to represent a negative number. Whitespace before or after the number is OK, and you may use underscores to separate groups of digits (in any base). For decimal strings, scientific notation (e.g. 1.1e4) is also accepted. It is also possible to affix one of the units "wei", "gwei", "shannon", "finney", "szabo", or "ether" (these are case-insensitive) onto a decimal numeric string (you may include space inbetween the quantity and the unit) to act as a multiplier (where here the assumption is that 1 wei means the number 1). You may also use a unit by itself, with no specified quantity, to mean 1 of that unit. (E.g., an input of "wei" will be interpreted as 1.) Note that it's OK if the quantity before the unit is not itself an integer, so long as the overall resulting quantity is an integer; e.g., "1.1 gwei" is legal integer input. In addition to giving the input in any of these obviously numeric forms, the input may also be given a a Uint8Array or anything that mimics one (see above about bytestrings); in this case the input will be interpreted as the big-endian byte representation of an unsigned integer (or in other words, it will be interpreted as base 256). Negative numbers cannot be represented in this way. Finally, the input may be given as a UintValue, IntValue, UfixedValue, FixedValue, [[Format.Values.UserDefinedTypeValue|UserDefinedTypeValue]] on top of one of these, or EnumValue; the type is not required to match unless strict checking is on (see resolveAndWrap), in which case the type must match exactly. In addition, the input may also be a EnumErrorResult so long as the error is a EnumOutOfRangeError; other types of error results are not accepted.

    Enums: Enums accept all the same forms of input as integer types. However, if the encoder is aware that a particular argument or field is in fact an enum and not just an integer, it accepts one additional form of input; the input may be a string (or String) containing the name of the enumerated option. So, for instance, given the following Solidity code:

    contract MyContract {
    enum Ternary {
    No, Yes, Maybe
    }
    }

    then "Yes" would be a valid input for an enum of type MyContract.Ternary. Moreover, "Ternary.Yes" and "MyContract.Ternary.Yes" would also work; these latter forms will only match enum types with the appropriate name and optionally defining contract, so you can use these to restrict matching for overload resolution, much like type/value input. Note these forms do not require the enum to be defined inside of a contract; those defined outside of contracts are supported too, so long as the encoder was initialized to know about them.

    Bytestrings: Bytestrings can be given in several forms. Note that for all forms of input, if the specified type is bytesN, it is OK if the length of the input is shorter than N bytes; it will automatically be right-padded with zero bytes in this case. (The exception is if the input is a BytesValue and strict checking is on; see resolveAndWrap.) Bytestrings may be given as "0x"-prefixed even-length hex strings (a String may be used in place of a string); underscores may be used to separate groups of hex digits. Bytestrings may also be given as a Uint8Array, or anything resembling a Uint8Array -- any object with a length field which is a number, and which has fields from 0 to length-1 all numbers from 0 to 255, will be accepted. Input may also be given as a BytesValue or a [[Format.Values.UserDefinedTypeValue|UserDefinedTypeValue]] on top of one; the specific type does not have to match unless strict checking is on. In addition, a bytestring may be given as an object with just the fields text and encoding; in this case, text should be a string (it must not have invalid UTF-16) and encoding an encoding to encode it as. The only supported encoding currently is "utf8". Finally, for compatibility with ethers, when strict checking is off (see resolveAndWrap), a bytestring of dynamic length (bytes) may have its input given numerically. The valid formats for this are the same as for integer types, except that wrapped numeric values are not accepted, numeric strings may not use scientific notation or units, and the number may not be negative. For compatibility reasons, if the number zero is given as input in this way, it will be treated as a bytestring consisting of a single zero byte, rather than the empty bytestring. Warning: an odd-length hex string will be treated as numeric input! (Effectively, it will be padded on the left with a zero hex digit.)

    Addresses and contracts: Input may be given as a hex string representing 20 bytes, with capitalization according to the Ethereum address checksum. The "0x" prefix is optional. If the hex string is all lowercase or all uppercase, however, then the checksum check will be skipped, and the input accepted regardless. Input may also be given as an ICAP address; again, the checksum must be correct. Finally, if ENS resolution has been configured, input may be given as an ENS name. All of these may also be given as Strings instead of strings. Input may also be given as an object with an address field, although the contents of that address field must be a "0x"-prefixed hex string (not String), and not any other address format. Input may also be given as a AddressValue, [[Format.Values.UserDefinedTypeValue|UserDefinedTypeValue]] on top of such, or ContractValue; the specific type does not matter.

    Booleans: Unless the strictBooleans option is passed, almost any input is accepted (as long as it's not type/value input for a different type), but how it is interpreted depends on the input. A boolean will be interpreted in the obvious way, and a Boolean will be unwrapped. A string will be considered true unless it is falsy or is equal (ignoring case) to the string "false"; however, if strictBooleans is passed, then only strings that are (ignoring case) equal to "true" or "false" will be accepted. A String will be considered true if and only if the underlying string is. A number will be considered true so long as it is truthy, and a Number will be considered true if and only if the underlying number is. A BoolValue, or [[Format.Values.UserDefinedTypeValue|UserDefinedTypeValue]] on top of such, will be considered true so long as it represents a true value. Moreover, two types of BoolErrorResult also count as true: Those where the error is a BoolOutOfRangeError and those where the error is a BoolPaddingError. This also applies to a [[Format.Errors.UserDefinedTypeValue|UserDefinedTypeErrors]] on top of one of these. All other error results, and all Values that are not BoolValues or a [[Format.Values.UserDefinedTypeValue|UserDefinedTypeValue]] on top of one, will be rejected. All other inputs will be considered true so long as they are truthy, unless strictBooleans is passed, in which case they will be rejected.

    Decimal fixed-point types: Input for fixed-point decimal types is similar to input for integer types. The differences are as follows:

    • Units are not accepted in numeric strings (or Strings).
    • Hexadecimal, octal, and binary strings (or Strings) are not accepted.
    • Uint8Arrays, or objects that mimic them, are not accepted.
    • Numeric values do not have to be integral. Note that if the input is a number (or Number) or MikeMcl BigNumber, it must be a finite value. Also, the number of decimal places in the input may not exceed the number of decimal places allowed in the type. Finally, just as integer types do not allow numbers (or Numbers) that are unsafe integers as input, decimal types will not accept a number (or Number) as input if that number is outside the safe range for that type, i.e., it is large enough that there may be loss of precision. (This means that 1 is not valid input for a fixed128x18!) Using other, safer, forms of input is encouraged.

    User-defined value types: These take exactly the same input as the underlying type.

    Arrays: The input may be an array, or it may be a ArrayValue. In the latter case, whether it is static-length or dynamic-length does not need to match (unless strict checking is on, see resolveAndWrap). If the allowJson option is passed, the array may also be a JSON string. Note that any allowed format is allowed for the individual elements.

    Structs and tuples: The input can be given either as an array or as an object; if the allowJson option is passed, it may also be given as a JSON string for one of these (any format is allowed for the individual elements). If given as an array, the elements should be the members of the struct/tuple, in order. If given as an object, it should be keyed by the struct or tuple's field names; if any of the elements of the tuple are unnamed, then input cannot be given as an object. Additional keys are also allowed unless strict checking is on. Input may also be given as a StructValue or TupleValue; the specific type does not matter.

    External function pointers: These may be given as an object with fields address and selector (additional fields are allowed); the address field may be anything that would be recognized as an address (see above), and the selector field may be anything that would be recgonized as a bytes4 (see above). Alternatively, this may be given as a bytestring (even length "0x"-prefixed hex string or String) of 24 bytes, specifying the address followed by the selector; in this case, the address does not need to be checksummed. Finally, input may of course also be given as a FunctionExternalValue; its more specific type does not matter.

    • Transaction options: These are given as an object with fields for the desired options (you can leave options out or have them be undefined and they'll be ignored). Note that, in order to maintain compatibility with older versions of Truffle, additional keys are accepted, but there must be at least one key that belongs in a transaction options object. Note that if any field exists, and is not undefined, but the value of that field cannot be interpreted as input of the appropriate type, the input will be rejected. Otherwise, inputs for each field can be anything that the encoder will understand for this field. Accepted fields are:
      • gas, gasPrice, value, nonce: These take integer input (see above).
      • from, to: These take address input (see above).
      • data: This takes bytes input (see above).
      • overwrite: This takes boolean input (see above).
      • type: This takes integer input, which must be in the range from 0 to 0xbf.
      • accessList: This takes input as if for an array of type AccessListForAddress[], if AccessListForAddress were a struct with two fields, address and storageKeys, with address being an address and storageKeys being of type uint256[]. Yes, this means storage keys may be given numerically; it also means that if a storage key is given as a hex string representing less than 32 bytes, it will be padded on the left, rather than on the right.
      • privateFor: This one is a special case, and requires a specific form of input. Input must be an array of base64-encoded bytestrings (as strings or Strings), each with a decoded length of 32 bytes. In addition, input may also be given as a OptionsValue.

    Parameters

    • abisOrNameOrSig: string | FunctionEntry[]

      The ABI entries for the overloads, or the name or full signature of the function. Note that if you are inputting ABI entries, they must be for functions, not constructors. The entries must be ones associated with this contract.

    • inputs: unknown[]
    • options: ResolveOptions = {}

    Returns Promise<TxAndAbi>

    An object with a tx field, holding the transaction options, including the encoded data, and an abi field, indicating which ABI entry was used for encoding.

  • encodeTxNoResolution(abi: FunctionEntry | ConstructorEntry, inputs: unknown[], options?: ResolveOptions): Promise<Options>
  • This method is asynchronous.

    This method is similar to encodeTransaction, except that it does not perform overload resolution; it takes a single ABI entry, rather than a list of them or a function name. Note that unlike encodeTransaction, it can also encode contract creation transactions.

    Because this method does not perform overload resolution, it only returns the resulting transaction options (including the encoded data), and does not bother returning the ABI used (as this was user-supplied.)

    If the allowOptions flag is set in the options argument, the input may contain an additional transaction options argument after the other arguments. Any non-data options not specified in such a transaction options argument will be simply omitted; it you want some options to have defaults, it is up to the you to set these options as appropriate afterwards.

    If the transaction options parameter has a data option, this option will be recognized but ignored. Similarly, when encoding a contract creation, the to option will also be ignored.

    See encodeTransaction for documentation of most of the inputs.

    Parameters

    • abi: FunctionEntry | ConstructorEntry

      The ABI entry for the transaction to encode for. Note it must be one for this contract. May be for either a function or a constructor.

    • inputs: unknown[]
    • options: ResolveOptions = {}

    Returns Promise<Options>

    The resulting transaction options, including the encoded data.

  • This method is asynchronous.

    Constructs a contract instance encoder for a given instance of the contract this encoder is for.

    Parameters

    • Optional address: string

      The address of the contract instance. If omitted, it will be autodetected. If an invalid address is provided, this method will throw an exception.

    Returns Promise<ContractInstanceEncoder>

  • getAbis(abisOrNameOrSig: string | FunctionEntry[]): FunctionEntry[]
  • getConstructorAbi(): ConstructorEntry
  • getConstructorMethod(abi?: ConstructorEntry): Method
  • getMethod(abi: FunctionEntry | ConstructorEntry): Method
  • resolveAndWrap(abisOrNameOrSig: string | FunctionEntry[], inputs: unknown[], options?: ResolveOptions): Promise<Resolution>
  • This method is asynchronous.

    This method attempts to perform overload resolution given user input to one of several possible methods. If the given input matches more than one of these methods, it will attempt to select the best match. See encodeTransaction for documentation of the acccepted input forms.

    If it is not possible for the given input to match any of the given methods, either a TypeMismatchError or a NoOverloadsMatchedError will be thrown. If more than one overload matches but none can be considered the unique best, you will get a NoUniqueBestOverloadError. If due to inputting a nonexistent function name there are no overloads to check, you will get a [[NoFunctionByThatNameError]].

    If the allowOptions flag is set in the options argument, the input may contain an additional transaction options argument after the other arguments.

    Note that use of the encoder for transactions to be sent to libraries is presently not supported and may have unreliable results. Limited support for this is planned for future versions.

    Overload resolution system

    If it is necessary to perform overload resolution by type rather than simply by length, the encoder will select among the overloads that could work the one it considers to be the best match. To be the best match, it must be a best match for each argument. An overload is a best match for a given argument if the type it would assign that argument is highest-priority among all types it could assign that argument (selected from overloads that match overall).

    Note that when doing this the match checker will be somewhat stricter than usual; inputs for structs/tuples will not be allowed to contain extra keys, numeric input (including odd-length hex strings) will not be accepted for dynamic-length bytestrings, and if a value is given as a Value, it will only match its specific type, rather than being allowed to match other types as usual (unless it is itself wrapped in a type/value pair).

    The overall order of priority of types is as follows:

    1. transaction options
    2. arrays
    3. structs and tuples
    4. addresses and contracts
    5. bytestrings (bytesN and bytes)
    6. external function pointers
    7. numeric types
    8. enums
    9. string
    10. bool

    (Note that if the encoder does not know that a certain argument is supposed to be an enum, it will of course just be treated as the underlying numeric type.)

    Moreover, within each category there is a priority ordering (which is not always total). Specifically:

    • For arrays, if S has priority over T, then S[] has priority over T[], and S[n] has priority over T[n]. Moreover, S[n] has priority over S[] and so also over T[].
    • Structs and tuples mostly act the same as the overall arguments list; for one such type S to have priority over another type T, each member type of S must have priority over the corresponding member type of T (correspondence being determined by the order of the members). However, if the two types S and T also have exactly the same component names (and each has all of its components named), then this will also be checked with correspondence by name instead of position, and S will only be considered more specific than T if both checks pass.
    • bytesN has priority over bytesM if N<=M, and has priority over bytes
    • A numeric type S has priority over a numeric type T if the values representable by S are a subset of those representable by T.

    If you are not getting the overload you want, you can use explicit type-value input as discussed in the documentation for encodeTransaction, or you can skip overload resolution and explicitly select an overload by other means. For enums you may also specify the enum type as documented in encodeTransaction.

    Parameters

    • abisOrNameOrSig: string | FunctionEntry[]

      The ABI entries for the overloads, or the name or full signature of the function. Note that if you are inputting ABI entries, they must be for functions, not constructors. The entries must be ones associated with this contract.

    • inputs: unknown[]

      An array of the inputs to the transaction. May include a transaction options argument on the end if the allowOptions flag is set.

    • options: ResolveOptions = {}

      Contains options to control the operation of this method.

    Returns Promise<Resolution>

    The interpretation of the input and the resolved method, as a Resolution object.

  • wrap(dataType: Type, input: unknown): Promise<Value>
  • wrapForTransaction(abi: FunctionEntry | ConstructorEntry, inputs: unknown[], options?: ResolveOptions): Promise<Resolution>
  • This method is asynchronous.

    This method recognizes user input for a transaction. It will throw a TypeMismatchError if it cannot do this. This method requires that the precise function be specified; it does not perofrm overload resolution. See encodeTransaction for documentation of the accepted forms of input.

    If the allowOptions flag is set in the options argument, the input may contain an additional transaction options argument after the other arguments.

    Note that use of the encoder for transactions to be sent to libraries is presently not supported and may have unreliable results. Limited support for this is planned for future versions.

    Parameters

    • abi: FunctionEntry | ConstructorEntry
    • inputs: unknown[]

      An array of the inputs to the transaction. May include a transaction options argument on the end if the allowOptions flag is set.

    • options: ResolveOptions = {}

      Contains options to control the operation of this method.

    Returns Promise<Resolution>

    The interpretation of the input, as a Resolution object.

Generated using TypeDoc