Skip to content

fix: replaced AnyObject with Any #725

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

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ class WalletViewController: UIViewController {
let manager = KeystoreManager([myWeb3KeyStore])
let address = keystore?.addresses?.first
#if DEBUG
print("Address :::>>>>> ", address as Any)
print("Address :::>>>>> ", manager.addresses as Any)
print("Address :::>>>>> ", address)
print("Address :::>>>>> ", manager.addresses)
#endif
let walletAddress = manager.addresses?.first?.address
self.walletAddressLabel.text = walletAddress ?? "0x"

print(walletAddress as Any)
print(walletAddress)
} else {
print("error")
}
Expand All @@ -115,7 +115,7 @@ class WalletViewController: UIViewController {
}
func importWalletWith(mnemonics: String) {
let walletAddress = try? BIP32Keystore(mnemonics: mnemonics , prefixPath: "m/44'/77777'/0'/0")
print(walletAddress?.addresses as Any)
print(walletAddress?.addresses)
self.walletAddressLabel.text = "\(walletAddress?.addresses?.first?.address ?? "0x")"

}
Expand All @@ -137,15 +137,15 @@ extension WalletViewController {
self._mnemonics = tMnemonics
print(_mnemonics)
let tempWalletAddress = try? BIP32Keystore(mnemonics: self._mnemonics , prefixPath: "m/44'/77777'/0'/0")
print(tempWalletAddress?.addresses?.first?.address as Any)
print(tempWalletAddress?.addresses?.first?.address)
guard let walletAddress = tempWalletAddress?.addresses?.first else {
self.showAlertMessage(title: "", message: "We are unable to create wallet", actionName: "Ok")
return
}
self._walletAddress = walletAddress.address
let privateKey = try tempWalletAddress?.UNSAFE_getPrivateKeyData(password: "", account: walletAddress)
#if DEBUG
print(privateKey as Any, "Is the private key")
print(privateKey, "Is the private key")
#endif
let keyData = try? JSONEncoder().encode(tempWalletAddress?.keystoreParams)
FileManager.default.createFile(atPath: userDir + "/keystore"+"/key.json", contents: keyData, attributes: nil)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ let response = try await readTX.callContractMethod()
let abiString = "[]" // some ABI string
let bytecode = Data.fromHex("") // some ABI bite sequence
let contract = web3.contract(abiString, at: nil, abiVersion: 2)!
let parameters = [...] as [AnyObject]
let parameters: [Any] = [...]
let deployOp = contract.prepareDeploy(bytecode: bytecode, constructor: contract.contract.constructor, parameters: parameters)!
deployOp.transaction.from = "" // your address
deployOp.transaction.gasLimitPolicy = .manual(3000000)
Expand Down
6 changes: 3 additions & 3 deletions Sources/Core/EthereumABI/ABIElements.swift
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ public extension ABI {
// MARK: - Function parameters encoding

extension ABI.Element {
public func encodeParameters(_ parameters: [AnyObject]) -> Data? {
public func encodeParameters(_ parameters: [Any]) -> Data? {
switch self {
case .constructor(let constructor):
return constructor.encodeParameters(parameters)
Expand All @@ -192,7 +192,7 @@ extension ABI.Element {
}

extension ABI.Element.Constructor {
public func encodeParameters(_ parameters: [AnyObject]) -> Data? {
public func encodeParameters(_ parameters: [Any]) -> Data? {
guard parameters.count == inputs.count else { return nil }
return ABIEncoder.encode(types: inputs, values: parameters)
}
Expand All @@ -203,7 +203,7 @@ extension ABI.Element.Function {
/// Encode parameters of a given contract method
/// - Parameter parameters: Parameters to pass to Ethereum contract
/// - Returns: Encoded data
public func encodeParameters(_ parameters: [AnyObject]) -> Data? {
public func encodeParameters(_ parameters: [Any]) -> Data? {
guard parameters.count == inputs.count,
let data = ABIEncoder.encode(types: inputs, values: parameters) else { return nil }
return methodEncoding + data
Expand Down
16 changes: 8 additions & 8 deletions Sources/Web3Core/Contract/ContractProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import BigInt
/// let inputArgsTypes: [ABI.Element.InOut] = [.init(name: "firstArgument", type: ABI.Element.ParameterType.string),
/// .init(name: "secondArgument", type: ABI.Element.ParameterType.uint(bits: 256))]
/// let constructor = ABI.Element.Constructor(inputs: inputArgsTypes, constant: false, payable: payable)
/// let constructorArguments = ["This is the array of constructor arguments", 10_000] as [AnyObject]
/// let constructorArguments: [Any] = ["This is the array of constructor arguments", 10_000]
///
/// contract.deploy(bytecode: smartContractBytecode,
/// constructor: constructor,
Expand All @@ -48,7 +48,7 @@ import BigInt
///
/// ```swift
/// let contract = EthereumContract(abiString)
/// let constructorArguments = ["This is the array of constructor arguments", 10_000] as [AnyObject]
/// let constructorArguments: [Any] = ["This is the array of constructor arguments", 10_000]
///
/// contract.deploy(bytecode: smartContractBytecode,
/// constructor: contract.constructor,
Expand Down Expand Up @@ -121,7 +121,7 @@ public protocol ContractProtocol {
/// - Returns: Encoded data for a given parameters, which is should be assigned to ``CodableTransaction.data`` property
func deploy(bytecode: Data,
constructor: ABI.Element.Constructor?,
parameters: [AnyObject]?,
parameters: [Any]?,
Copy link
Collaborator

Choose a reason for hiding this comment

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

I see that in some places you drop a type erasure totally, while in others you've left it, but change the target type to Any? Within my review I assume that you do this in following logic: in case if type erasure it was removed, in case its required target type has ben set to Any. Tell me if i'm wrong with that, resolve this otherwise.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Could you please provide one or more examples where I did the following:

in some places you drop a type erasure totally

I'll start to self-review this PR only now.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

To remove any misunderstanding: the goal I had in mind is to eliminate the use AnyObject as much as possible. I simply performed the replacement of AnyObject with Any, ran the tests, fixed almost all issues that occurred (except ENS tests) and opened this PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

AnyObject uses bridged types and basically changes the type of the object when it can.
For example:

  • String -> NSString;
  • Int -> NSNumber;
  • Array -> NSArray;
  • struct -> __SwiftValue;
  • etc.

While using Any we preserve this information.

Screenshot 2023-01-13 at 21 09 16

Screenshot 2023-01-13 at 21 04 38

And this is where it gets important!
When we have Int8, Int16, Int.. and UInt[8-64] these all get represented as NSNumber if we cast them to AnyObject. And here is an example of what will happen:
Screenshot 2023-01-13 at 21 19 13

Screenshot 2023-01-13 at 21 19 29

We do not want to represent Int8 as Int or the other way around.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess I've finally got the point. AnyObject is about bridging swift types to an Obj-C one, but with type erasure. Guess it's some internal apple demand at its most.

extraData: Data?) -> Data?

/// Creates function call transaction with data set as `method` encoded with given `parameters`.
Expand All @@ -134,7 +134,7 @@ public protocol ContractProtocol {
/// - parameters: method input arguments;
/// - extraData: additional data to append at the end of `transaction.data` field;
/// - Returns: transaction object if `method` was found and `parameters` were successfully encoded.
func method(_ method: String, parameters: [AnyObject], extraData: Data?) -> Data?
func method(_ method: String, parameters: [Any], extraData: Data?) -> Data?

/// Decode output data of a function.
/// - Parameters:
Expand Down Expand Up @@ -190,7 +190,7 @@ extension ContractProtocol {
/// See ``ContractProtocol/deploy(bytecode:constructor:parameters:extraData:)`` for details.
func deploy(_ bytecode: Data,
constructor: ABI.Element.Constructor? = nil,
parameters: [AnyObject]? = nil,
parameters: [Any]? = nil,
extraData: Data? = nil) -> Data? {
deploy(bytecode: bytecode,
constructor: constructor,
Expand All @@ -203,7 +203,7 @@ extension ContractProtocol {
///
/// See ``ContractProtocol/method(_:parameters:extraData:)`` for details.
func method(_ method: String = "fallback",
parameters: [AnyObject]? = nil,
parameters: [Any]? = nil,
extraData: Data? = nil) -> Data? {
self.method(method, parameters: parameters ?? [], extraData: extraData)
}
Expand All @@ -222,7 +222,7 @@ extension DefaultContractProtocol {
// MARK: Writing Data flow
public func deploy(bytecode: Data,
constructor: ABI.Element.Constructor?,
parameters: [AnyObject]?,
parameters: [Any]?,
extraData: Data?) -> Data? {
var fullData = bytecode

Expand Down Expand Up @@ -258,7 +258,7 @@ extension DefaultContractProtocol {
/// - data: parameters + extraData
/// - params: EthereumParameters with no contract method call encoded data.
public func method(_ method: String,
parameters: [AnyObject],
parameters: [Any],
extraData: Data?) -> Data? {
// MARK: - Encoding ABI Data flow
if method == "fallback" {
Expand Down
48 changes: 24 additions & 24 deletions Sources/Web3Core/EthereumABI/ABIDecoding.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import BigInt
public struct ABIDecoder { }

extension ABIDecoder {
public static func decode(types: [ABI.Element.InOut], data: Data) -> [AnyObject]? {
public static func decode(types: [ABI.Element.InOut], data: Data) -> [Any]? {
let params = types.compactMap { el -> ABI.Element.ParameterType in
return el.type
}
return decode(types: params, data: data)
}

public static func decode(types: [ABI.Element.ParameterType], data: Data) -> [AnyObject]? {
var toReturn = [AnyObject]()
public static func decode(types: [ABI.Element.ParameterType], data: Data) -> [Any]? {
var toReturn = [Any]()
var consumed: UInt64 = 0
for i in 0 ..< types.count {
let (v, c) = decodeSingleType(type: types[i], data: data, pointer: consumed)
Expand All @@ -29,7 +29,7 @@ extension ABIDecoder {
return toReturn
}

public static func decodeSingleType(type: ABI.Element.ParameterType, data: Data, pointer: UInt64 = 0) -> (value: AnyObject?, bytesConsumed: UInt64?) {
public static func decodeSingleType(type: ABI.Element.ParameterType, data: Data, pointer: UInt64 = 0) -> (value: Any?, bytesConsumed: UInt64?) {
let (elData, nextPtr) = followTheData(type: type, data: data, pointer: pointer)
guard let elementItself = elData, let nextElementPointer = nextPtr else {
return (nil, nil)
Expand All @@ -40,18 +40,18 @@ extension ABIDecoder {
let mod = BigUInt(1) << bits
let dataSlice = elementItself[0 ..< 32]
let v = BigUInt(dataSlice) % mod
return (v as AnyObject, type.memoryUsage)
return (v, type.memoryUsage)
case .int(let bits):
guard elementItself.count >= 32 else {break}
let mod = BigInt(1) << bits
let dataSlice = elementItself[0 ..< 32]
let v = BigInt.fromTwosComplement(data: dataSlice) % mod
return (v as AnyObject, type.memoryUsage)
return (v, type.memoryUsage)
case .address:
guard elementItself.count >= 32 else {break}
let dataSlice = elementItself[12 ..< 32]
let address = EthereumAddress(dataSlice)
return (address as AnyObject, type.memoryUsage)
return (address, type.memoryUsage)
case .bool:
guard elementItself.count >= 32 else {break}
let dataSlice = elementItself[0 ..< 32]
Expand All @@ -60,32 +60,32 @@ extension ABIDecoder {
v == BigUInt(32) ||
v == BigUInt(28) ||
v == BigUInt(1) {
return (true as AnyObject, type.memoryUsage)
return (true, type.memoryUsage)
} else if v == BigUInt(35) ||
v == BigUInt(31) ||
v == BigUInt(27) ||
v == BigUInt(0) {
return (false as AnyObject, type.memoryUsage)
return (false, type.memoryUsage)
}
case .bytes(let length):
guard elementItself.count >= 32 else {break}
let dataSlice = elementItself[0 ..< length]
return (dataSlice as AnyObject, type.memoryUsage)
return (dataSlice, type.memoryUsage)
case .string:
guard elementItself.count >= 32 else {break}
var dataSlice = elementItself[0 ..< 32]
let length = UInt64(BigUInt(dataSlice))
guard elementItself.count >= 32+length else {break}
dataSlice = elementItself[32 ..< 32 + length]
guard let string = String(data: dataSlice, encoding: .utf8) else {break}
return (string as AnyObject, type.memoryUsage)
return (string, type.memoryUsage)
case .dynamicBytes:
guard elementItself.count >= 32 else {break}
var dataSlice = elementItself[0 ..< 32]
let length = UInt64(BigUInt(dataSlice))
guard elementItself.count >= 32+length else {break}
dataSlice = elementItself[32 ..< 32 + length]
return (dataSlice as AnyObject, nextElementPointer)
return (dataSlice, nextElementPointer)
case .array(type: let subType, length: let length):
switch type.arraySize {
case .dynamicSize:
Expand All @@ -97,14 +97,14 @@ extension ABIDecoder {
guard elementItself.count >= 32 + subType.memoryUsage*length else {break}
dataSlice = elementItself[32 ..< 32 + subType.memoryUsage*length]
var subpointer: UInt64 = 32
var toReturn = [AnyObject]()
var toReturn = [Any]()
for _ in 0 ..< length {
let (v, c) = decodeSingleType(type: subType, data: elementItself, pointer: subpointer)
guard let valueUnwrapped = v, let consumedUnwrapped = c else {break}
toReturn.append(valueUnwrapped)
subpointer = subpointer + consumedUnwrapped
}
return (toReturn as AnyObject, type.memoryUsage)
return (toReturn, type.memoryUsage)
} else {
// in principle is true for tuple[], so will work for string[] too
guard elementItself.count >= 32 else {break}
Expand All @@ -113,7 +113,7 @@ extension ABIDecoder {
guard elementItself.count >= 32 else {break}
dataSlice = Data(elementItself[32 ..< elementItself.count])
var subpointer: UInt64 = 0
var toReturn = [AnyObject]()
var toReturn = [Any]()
for _ in 0 ..< length {
let (v, c) = decodeSingleType(type: subType, data: dataSlice, pointer: subpointer)
guard let valueUnwrapped = v, let consumedUnwrapped = c else {break}
Expand All @@ -124,11 +124,11 @@ extension ABIDecoder {
subpointer = consumedUnwrapped // need to go by nextElementPointer
}
}
return (toReturn as AnyObject, nextElementPointer)
return (toReturn, nextElementPointer)
}
case .staticSize(let staticLength):
guard length == staticLength else {break}
var toReturn = [AnyObject]()
var toReturn = [Any]()
var consumed: UInt64 = 0
for _ in 0 ..< length {
let (v, c) = decodeSingleType(type: subType, data: elementItself, pointer: consumed)
Expand All @@ -137,15 +137,15 @@ extension ABIDecoder {
consumed = consumed + consumedUnwrapped
}
if subType.isStatic {
return (toReturn as AnyObject, consumed)
return (toReturn, consumed)
} else {
return (toReturn as AnyObject, nextElementPointer)
return (toReturn, nextElementPointer)
}
case .notArray:
break
}
case .tuple(types: let subTypes):
var toReturn = [AnyObject]()
var toReturn = [Any]()
var consumed: UInt64 = 0
for i in 0 ..< subTypes.count {
let (v, c) = decodeSingleType(type: subTypes[i], data: elementItself, pointer: consumed)
Expand Down Expand Up @@ -173,14 +173,14 @@ extension ABIDecoder {
}
}
if type.isStatic {
return (toReturn as AnyObject, consumed)
return (toReturn, consumed)
} else {
return (toReturn as AnyObject, nextElementPointer)
return (toReturn, nextElementPointer)
}
case .function:
guard elementItself.count >= 32 else {break}
let dataSlice = elementItself[8 ..< 32]
return (dataSlice as AnyObject, type.memoryUsage)
return (dataSlice, type.memoryUsage)
}
return (nil, nil)
}
Expand Down Expand Up @@ -236,7 +236,7 @@ extension ABIDecoder {
return inp.type
}
guard logs.count == indexedInputs.count + 1 else {return nil}
var indexedValues = [AnyObject]()
var indexedValues = [Any]()
for i in 0 ..< indexedInputs.count {
let data = logs[i+1]
let input = indexedInputs[i]
Expand Down
6 changes: 3 additions & 3 deletions Sources/Web3Core/EthereumABI/ABIElements.swift
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ public extension ABI {
// MARK: - Function parameters encoding

extension ABI.Element {
public func encodeParameters(_ parameters: [AnyObject]) -> Data? {
public func encodeParameters(_ parameters: [Any]) -> Data? {
switch self {
case .constructor(let constructor):
return constructor.encodeParameters(parameters)
Expand All @@ -193,7 +193,7 @@ extension ABI.Element {
}

extension ABI.Element.Constructor {
public func encodeParameters(_ parameters: [AnyObject]) -> Data? {
public func encodeParameters(_ parameters: [Any]) -> Data? {
guard parameters.count == inputs.count else { return nil }
return ABIEncoder.encode(types: inputs, values: parameters)
}
Expand All @@ -204,7 +204,7 @@ extension ABI.Element.Function {
/// Encode parameters of a given contract method
/// - Parameter parameters: Parameters to pass to Ethereum contract
/// - Returns: Encoded data
public func encodeParameters(_ parameters: [AnyObject]) -> Data? {
public func encodeParameters(_ parameters: [Any]) -> Data? {
guard parameters.count == inputs.count,
let data = ABIEncoder.encode(types: inputs, values: parameters) else { return nil }
return methodEncoding + data
Expand Down
Loading