Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixed parsing of ABIs with tuples + wrong gas info when transactionOptions created from json #379

Merged
merged 4 commits into from
Oct 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion Sources/web3swift/EthereumABI/ABIDecoding.swift
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,12 @@ extension ABIDecoder {
let (v, c) = decodeSignleType(type: subType, data: dataSlice, pointer: subpointer)
guard let valueUnwrapped = v, let consumedUnwrapped = c else {break}
toReturn.append(valueUnwrapped)
subpointer = subpointer + consumedUnwrapped
if (subType.isStatic) {
subpointer = subpointer + consumedUnwrapped
}
else {
subpointer = consumedUnwrapped // need to go by nextElementPointer
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Breaks decoding of arrays that contain any type that is not static.
That would be string, dynamicBytes, array and tuple that contain non-static types.

@izakpavel Could you please explain what you meant by this comment?

// need to go by nextElementPointer

Thanks!

Copy link
Collaborator

@JeneaVranceanu JeneaVranceanu Mar 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is an example with values that I'm working with.
What I'm doing is encoding two arrays and using that result as an argument for the decoding function.

This is the first array to be encoded.
ABI.Element.ParameterType is array(bytes(32)):

[0] - 0xdf30dba06db6a30e65354d9a64c609861f089545ca58c6b4dbe31a5f338cb0e3
[1] - 0x4b80742d0000000082ac000022300fd00e3402df12db7a0a054fae50f0bf91d7
[2] - 0x027545a85de73f6a6ec5ce14736fa7eb00000000000000000000000000000002

This is the second array to encoded.
ABI.Element.ParameterType is array(dynamicBytes) even though in this specific example all values are 32 bytes long:

[0] - 0x0000000000000000000000000000000000000000000000000000000000000003
[1] - 0x00000000000000000000000000000000000000000000000000000000000003fe
[2] - 0x22300fd00e3402df12db7a0a054fae50f0bf91d7000000000000000000000000

And this is how they are decoded:
Array with bytes(32):

[0] - 0xdf30dba06db6a30e65354d9a64c609861f089545ca58c6b4dbe31a5f338cb0e3
[1] - 0x4b80742d0000000082ac000022300fd00e3402df12db7a0a054fae50f0bf91d7
[2] - 0x027545a85de73f6a6ec5ce14736fa7eb00000000000000000000000000000002

Array with dynamicBytes:

[0] - 0x0000000000000000000000000000000000000000000000000000000000000003
[1] - 0x00000000000000000000000000000000000000000000000000000000000003fe
[2] - 0x00000000000000000000000000000000000000000000000000000000000003fe

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@BaldyAsh Please, take a look at this issue. It feels like reverting line 144 back to

subpointer = subpointer + consumedUnwrapped

would fix the issue.

Note: tested the suggestion above in a fork of web3swift and it does indeed fix the issue.
I'll test later with array(tuple) type as @izakpavel had issues with it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

array(tuple) does break indeed if line 144 is reverted to its previous logic.

}
}
return (toReturn as AnyObject, nextElementPointer)
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/web3swift/EthereumABI/ABIParameterTypes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ extension ABI.Element.ParameterType: ABIEncoding {
case .tuple(types: let types):
let typesRepresentation = types.map({return $0.abiRepresentation})
let typesJoined = typesRepresentation.joined(separator: ",")
return "tuple(\(typesJoined))"
return "(\(typesJoined))"
case .string:
return "string"
}
Expand Down
11 changes: 11 additions & 0 deletions Sources/web3swift/EthereumABI/ABIParsing.swift
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,17 @@ extension ABI.Input {
let nativeInput = ABI.Element.InOut(name: name, type: type)
return nativeInput
}
else if case .array(type: .tuple(types: _), length: _) = parameterType {
let components = try self.components?.compactMap({ (inp: ABI.Input) throws -> ABI.Element.ParameterType in
let input = try inp.parse()
return input.type
})
let tupleType = ABI.Element.ParameterType.tuple(types: components!)

let newType: ABI.Element.ParameterType = .array(type: tupleType, length: 0)
let nativeInput = ABI.Element.InOut(name: name, type: newType)
return nativeInput
}
else {
let nativeInput = ABI.Element.InOut(name: name, type: parameterType)
return nativeInput
Expand Down
2 changes: 1 addition & 1 deletion Sources/web3swift/Web3/Web3+Options.swift
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ public struct TransactionOptions {
public static func fromJSON(_ json: [String: Any]) -> TransactionOptions? {
var options = TransactionOptions()
if let gas = json["gas"] as? String, let gasBiguint = BigUInt(gas.stripHexPrefix().lowercased(), radix: 16) {
options.gasLimit = .limited(gasBiguint)
options.gasLimit = .manual(gasBiguint)
} else if let gasLimit = json["gasLimit"] as? String, let gasgasLimitBiguint = BigUInt(gasLimit.stripHexPrefix().lowercased(), radix: 16) {
options.gasLimit = .limited(gasgasLimitBiguint)
} else {
Expand Down