Skip to content

Commit eb32f20

Browse files
committed
update function documentation
1 parent 4521eb2 commit eb32f20

File tree

2 files changed

+19
-44
lines changed

2 files changed

+19
-44
lines changed

Sources/Web3Core/Contract/ContractProtocol.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,10 @@ public protocol ContractProtocol {
143143
/// - name with arguments:`myFunction(uint256)`.
144144
/// - method signature (with or without `0x` prefix, case insensitive): `0xFFffFFff`;
145145
/// - data: non empty bytes to decode;
146-
/// - Returns: dictionary with decoded values. `nil` if decoding failed.
146+
/// - Returns: dictionary with decoded values.
147+
/// - Throws:
148+
/// - `Web3Error.revert(String, String?)` when function call aborted by `revert(string)` and `require(expression, string)`.
149+
/// - `Web3Error.revertCustom(String, Dictionary)` when function call aborted by `revert CustomError()`.
147150
@discardableResult
148151
func decodeReturnData(_ method: String, data: Data) throws -> [String: Any]
149152

Sources/Web3Core/EthereumABI/ABIElements.swift

Lines changed: 15 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ extension ABI.Element.Constructor {
202202
extension ABI.Element.Function {
203203

204204
/// Encode parameters of a given contract method
205-
/// - Parameter parameters: Parameters to pass to Ethereum contract
205+
/// - Parameters: Parameters to pass to Ethereum contract
206206
/// - Returns: Encoded data
207207
public func encodeParameters(_ parameters: [Any]) -> Data? {
208208
guard parameters.count == inputs.count,
@@ -223,6 +223,10 @@ extension ABI.Element.Event {
223223
// MARK: - Decode custom error
224224

225225
extension ABI.Element.EthError {
226+
/// Decodes `revert CustomError(_)` calls.
227+
/// - Parameters:
228+
/// - data: bytes returned by a function call that stripped error signature hash.
229+
/// - Returns: a dictionary containing decoded data mappend to indices and names of returned values or nil if decoding failed.
226230
public func decodeEthError(_ data: Data) -> [String: Any]? {
227231
guard inputs.count * 32 <= data.count,
228232
let decoded = ABIDecoder.decode(types: inputs, data: data) else {
@@ -239,7 +243,7 @@ extension ABI.Element.EthError {
239243
return result
240244
}
241245

242-
/// Decodes `revert(string)` and `require(expression, string)` calls.
246+
/// Decodes `revert(string)` or `require(expression, string)` calls.
243247
/// These calls are decomposed as `Error(string)` error.
244248
public static func decodeStringError(_ data: Data) -> String? {
245249
let decoded = ABIDecoder.decode(types: [.init(name: "", type: .string)], data: data)
@@ -299,68 +303,36 @@ extension ABI.Element.Function {
299303
return ABIDecoder.decodeInputData(rawData, methodEncoding: methodEncoding, inputs: inputs)
300304
}
301305

302-
/// Decodes data returned by a function call. Able to decode `revert(string)`, `revert CustomError(...)` and `require(expression, string)` calls.
306+
/// Decodes data returned by a function call.
303307
/// - Parameters:
304308
/// - data: bytes returned by a function call;
305-
/// - errors: optional dictionary of known errors that could be returned by the function you called. Used to decode the error information.
306309
/// - Returns: a dictionary containing decoded data mappend to indices and names of returned values if these are not `nil`.
307-
/// If `data` is an error response returns dictionary containing all available information about that specific error. Read more for details.
310+
/// - Throws:
311+
/// - `Web3Error.processingError(desc: String)` when decode process failed.
308312
///
309313
/// Return cases:
310-
/// - when no `outputs` declared and `data` is not an error response:
314+
/// - when no `outputs` declared:
311315
/// ```swift
312-
/// ["_success": true]
316+
/// [:]
313317
/// ```
314318
/// - when `outputs` declared and decoding completed successfully:
315319
/// ```swift
316-
/// ["_success": true, "0": value_1, "1": value_2, ...]
320+
/// ["0": value_1, "1": value_2, ...]
317321
/// ```
318322
/// Additionally this dictionary will have mappings to output names if these names are specified in the ABI;
319-
/// - function call was aborted using `revert(message)` or `require(expression, message)`:
320-
/// ```swift
321-
/// ["_success": false, "_abortedByRevertOrRequire": true, "_errorMessage": message]`
322-
/// ```
323-
/// - function call was aborted using `revert CustomMessage()` and `errors` argument contains the ABI of that custom error type:
324-
/// ```swift
325-
/// ["_success": false,
326-
/// "_abortedByRevertOrRequire": true,
327-
/// "_error": error_name_and_types, // e.g. `MyCustomError(uint256, address senderAddress)`
328-
/// "0": error_arg1,
329-
/// "1": error_arg2,
330-
/// ...,
331-
/// "error_arg1_name": error_arg1, // Only named arguments will be mapped to their names, e.g. `"senderAddress": EthereumAddress`
332-
/// "error_arg2_name": error_arg2, // Otherwise, you can query them by position index.
333-
/// ...]
334-
/// ```
335-
/// - in case of any error:
336-
/// ```swift
337-
/// ["_success": false, "_failureReason": String]
338-
/// ```
339-
/// Error reasons include:
340-
/// - `outputs` declared but at least one value failed to be decoded;
341-
/// - `data.count` is less than `outputs.count * 32`;
342-
/// - `outputs` defined and `data` is empty;
343-
/// - `data` represent reverted transaction
344-
///
345-
/// How `revert(string)` and `require(expression, string)` return value is decomposed:
346-
/// - `08C379A0` function selector for `Error(string)`;
347-
/// - next 32 bytes are the data offset;
348-
/// - next 32 bytes are the error message length;
349-
/// - the next N bytes, where N >= 32, are the message bytes
350-
/// - the rest are 0 bytes padding.
351323
public func decodeReturnData(_ data: Data) throws -> [String: Any] {
352324
guard !outputs.isEmpty else {
353325
NSLog("Function doesn't have any output types to decode given data.")
354326
return [:]
355327
}
356328

357329
guard outputs.count * 32 <= data.count else {
358-
throw Web3Error.revert("Bytes count must be at least \(outputs.count * 32). Given \(data.count). Decoding will fail.", reason: nil)
330+
throw Web3Error.processingError(desc: "Bytes count must be at least \(outputs.count * 32). Given \(data.count). Decoding will fail.")
359331
}
360332

361333
// TODO: need improvement - we should be able to tell which value failed to be decoded
362334
guard let values = ABIDecoder.decode(types: outputs, data: data) else {
363-
throw Web3Error.revert("Failed to decode at least one value.", reason: nil)
335+
throw Web3Error.processingError(desc: "Failed to decode at least one value.")
364336
}
365337
var returnArray: [String: Any] = [:]
366338
for i in outputs.indices {
@@ -411,7 +383,7 @@ extension ABI.Element.Function {
411383
/// // "_parsingError" is optional and is present only if decoding of custom error arguments failed
412384
/// "_parsingError": "Data matches MyCustomError(uint256, address senderAddress) but failed to be decoded."]
413385
/// ```
414-
@available(*, deprecated, message: "Use `ABI.Element.EthError.decodeEthError(_:)` instead")
386+
@available(*, deprecated, message: "Use decode function from `ABI.Element.EthError` instead")
415387
public func decodeErrorResponse(_ data: Data, errors: [String: ABI.Element.EthError]? = nil) -> [String: Any]? {
416388
/// If data is empty and outputs are expected it is treated as a `require(expression)` or `revert()` call with no message.
417389
/// In solidity `require(false)` and `revert()` calls return empty error response.

0 commit comments

Comments
 (0)