Skip to content

Commit ead7b71

Browse files
committed
Update to use new EthereumParameters struct
1 parent e340b70 commit ead7b71

File tree

8 files changed

+208
-200
lines changed

8 files changed

+208
-200
lines changed

Sources/web3swift/Transaction/AbstractEnvelope.swift

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import BigInt
2121
*/
2222

2323
/// Enumeration for supported transaction types
24-
public enum TransactionType: UInt, CustomStringConvertible {
24+
public enum TransactionType: UInt, CustomStringConvertible, CaseIterable {
2525

2626
/// For untyped and type 0 transactions EIP155 and older
2727
case legacy
@@ -33,16 +33,15 @@ public enum TransactionType: UInt, CustomStringConvertible {
3333
case eip1559
3434

3535
/// range-checking value, not a valid type, will never be returned as a type
36-
case total // always keep immediately after last valid type
36+
// case total // always keep immediately after last valid type
3737
// should there be a need to handle an unknown type, place it after total
3838

3939
public var description: String {
4040
switch self {
41-
case .legacy: return "Legacy" // legacy is a pseudo-type, no EIP-2718 transaction will ever be encoded with type = 0
42-
// though nodes do appear to return a type of 0 for legacy transactions in their JSON
41+
case .legacy: return "Legacy" // legacy is a pseudo-type, no EIP-2718 transaction will ever be encoded with type = 0
42+
// though nodes do appear to return a type of 0 for legacy transactions in their JSON
4343
case .eip2930: return "EIP-2930"
4444
case .eip1559: return "EIP-1559"
45-
default: return "Unknown EIP-2718 Type" // anything else is an invalid type
4645
}
4746
}
4847
}
@@ -70,18 +69,14 @@ public protocol AbstractEnvelope: CustomStringConvertible { // possibly add Coda
7069
/// the nonce value for the transaction
7170
var nonce: BigUInt { get set }
7271

73-
/// Blockchain `ChainID` that this transaction is or will be, signed for.
74-
/// Remains optional to support legacy transactions.
75-
var chainID: BigUInt? { get set }
76-
7772
/// On chain address that this transaction is being sent to
7873
var to: EthereumAddress { get set }
7974

80-
/// The native value of the transaction in Wei
81-
var value: BigUInt { get set }
75+
// /// The native value of the transaction in Wei
76+
// var value: BigUInt { get set }
8277

83-
/// Any encoded data accompanying the transaction
84-
var data: Data { get set }
78+
// /// Any encoded data accompanying the transaction
79+
// var data: Data { get set }
8580

8681
// Signature data should not be set directly
8782
/// signature V compoonent
@@ -93,6 +88,11 @@ public protocol AbstractEnvelope: CustomStringConvertible { // possibly add Coda
9388
/// signature S compoonent
9489
var s: BigUInt { get set }
9590

91+
/// Transaction Parameters object
92+
/// used to provide external access to the otherwise
93+
/// protected parameters of the object
94+
var parameters: EthereumParameters { get set }
95+
9696
// required initializers
9797
// for Decodable support
9898
/// initializer for creating an `EthereumTransaction` with the Decodable protocol
@@ -117,25 +117,17 @@ public protocol AbstractEnvelope: CustomStringConvertible { // possibly add Coda
117117
/// - Parameters:
118118
/// - to: EthereumAddress of destination
119119
/// - nonce: nonce for the transaction
120-
/// - chainID: chainId of the network the transaction belongs to
121-
/// - value: Native value in Wei of the transaction
122-
/// - data: Payload data for the transaction
123120
/// - v: Signature V component
124121
/// - r: Signature R component
125122
/// - s: Signature S component
126-
/// - options: TransactionOptions struct containing any other required parameters
127-
init(to: EthereumAddress, nonce: BigUInt?, chainID: BigUInt?, value: BigUInt?,
128-
data: Data, v: BigUInt, r: BigUInt, s: BigUInt, options: TransactionOptions?)
123+
/// - parameters: EthereumParameters struct containing any other required parameters
124+
init(to: EthereumAddress, nonce: BigUInt?, v: BigUInt, r: BigUInt, s: BigUInt, parameters: EthereumParameters?)
129125

130126
/// Applies the passed options to the transaction envelope
131127
/// - Parameters:
132128
/// - {default}: TransactionOptions struct
133129
mutating func applyOptions(_ options: TransactionOptions)
134130

135-
/// Create a TransactionOptions object representing this transaction
136-
/// - Returns: A TransactionOptions object with all parameters from the transaction set
137-
func getOptions() -> TransactionOptions
138-
139131
/// Transaction encoder for transmission or signing
140132
/// - Parameters:
141133
/// - {default}: EncodeType enum

Sources/web3swift/Transaction/EIP1559Envelope.swift

Lines changed: 45 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,7 @@ public struct EIP1559Envelope: EIP2718Envelope {
1212

1313
// common parameters for any transaction
1414
public var nonce: BigUInt = 0
15-
public var chainID: BigUInt? {
16-
get { return internalChainID }
17-
// swiftlint:disable force_unwrapping
18-
set(newID) { if newID != nil { internalChainID = newID! } }
19-
// swiftlint:enable force_unwrapping
20-
}
15+
public var chainID: BigUInt
2116
public var to: EthereumAddress
2217
public var value: BigUInt
2318
public var data: Data
@@ -46,8 +41,6 @@ public struct EIP1559Envelope: EIP2718Envelope {
4641
public var maxFeePerGas: BigUInt
4742
public var accessList: [AccessListEntry] // from EIP-2930
4843

49-
private var internalChainID: BigUInt
50-
5144
// for CustomStringConvertible
5245
public var description: String {
5346
var toReturn = ""
@@ -66,6 +59,35 @@ public struct EIP1559Envelope: EIP2718Envelope {
6659
toReturn += "s: " + String(self.s) + "\n"
6760
return toReturn
6861
}
62+
63+
public var parameters: EthereumParameters {
64+
get {
65+
return EthereumParameters(
66+
type: type,
67+
to: to,
68+
nonce: nonce,
69+
chainID: chainID,
70+
value: value,
71+
data: data,
72+
gasLimit: gasLimit,
73+
maxFeePerGas: maxFeePerGas,
74+
maxPriorityFeePerGas: maxPriorityFeePerGas,
75+
accessList: accessList
76+
)
77+
}
78+
set(val) {
79+
nonce = val.nonce ?? nonce
80+
chainID = val.chainID ?? chainID
81+
to = val.to ?? to
82+
value = val.value ?? value
83+
data = val.data ?? data
84+
gasLimit = val.gasLimit ?? gasLimit
85+
maxFeePerGas = val.maxFeePerGas ?? maxFeePerGas
86+
maxPriorityFeePerGas = val.maxPriorityFeePerGas ?? maxPriorityFeePerGas
87+
accessList = val.accessList ?? accessList
88+
}
89+
}
90+
6991
}
7092

7193
extension EIP1559Envelope {
@@ -94,7 +116,7 @@ extension EIP1559Envelope {
94116
guard container.contains(.v), container.contains(.r), container.contains(.s) else { return nil }
95117

96118
// everything we need is present, so we should only have to throw from here
97-
self.internalChainID = try container.decodeHexIfPresent(BigUInt.self, forKey: .chainId) ?? 0
119+
self.chainID = try container.decodeHexIfPresent(BigUInt.self, forKey: .chainId) ?? 0
98120
self.nonce = try container.decodeHex(BigUInt.self, forKey: .nonce)
99121

100122
let list = try? container.decode([AccessListEntry].self, forKey: .accessList)
@@ -160,7 +182,7 @@ extension EIP1559Envelope {
160182
guard let sData = rlpItem[RlpKey.sig_s.rawValue]!.data else { return nil }
161183
// swiftlint:enable force_unwrapping
162184

163-
self.internalChainID = BigUInt(chainData)
185+
self.chainID = BigUInt(chainData)
164186
self.nonce = BigUInt(nonceData)
165187
self.maxPriorityFeePerGas = BigUInt(maxPriorityData)
166188
self.maxFeePerGas = BigUInt(maxFeeData)
@@ -211,23 +233,20 @@ extension EIP1559Envelope {
211233
}
212234

213235
public init(to: EthereumAddress, nonce: BigUInt? = nil,
214-
chainID: BigUInt? = nil, value: BigUInt? = nil, data: Data,
215236
v: BigUInt = 1, r: BigUInt = 0, s: BigUInt = 0,
216-
options: TransactionOptions? = nil) {
237+
parameters: EthereumParameters? = nil) {
217238
self.to = to
218-
self.nonce = nonce ?? options?.resolveNonce(0) ?? 0
219-
self.internalChainID = chainID ?? 0
220-
self.value = value ?? options?.value ?? 0
221-
self.data = data
239+
self.nonce = nonce ?? parameters?.nonce ?? 0
240+
self.chainID = parameters?.chainID ?? 0
241+
self.value = parameters?.value ?? 0
242+
self.data = parameters?.data ?? Data()
222243
self.v = v
223244
self.r = r
224245
self.s = s
225-
// decode gas options, if present
226-
self.maxPriorityFeePerGas = options?.resolveMaxPriorityFeePerGas(0) ?? 0
227-
self.maxFeePerGas = options?.resolveMaxFeePerGas(0) ?? 0
228-
self.gasLimit = options?.resolveGasLimit(0) ?? 0
229-
// get the access list, if present
230-
self.accessList = options?.accessList ?? []
246+
self.maxPriorityFeePerGas = parameters?.maxPriorityFeePerGas ?? 0
247+
self.maxFeePerGas = parameters?.maxFeePerGas ?? 0
248+
self.gasLimit = parameters?.gasLimit ?? 0
249+
self.accessList = parameters?.accessList ?? []
231250
}
232251

233252
// memberwise
@@ -238,7 +257,7 @@ extension EIP1559Envelope {
238257
v: BigUInt = 1, r: BigUInt = 0, s: BigUInt = 0) {
239258
self.to = to
240259
self.nonce = nonce
241-
self.internalChainID = chainID
260+
self.chainID = chainID
242261
self.value = value
243262
self.data = data
244263
self.maxPriorityFeePerGas = maxPriorityFeePerGas
@@ -261,25 +280,13 @@ extension EIP1559Envelope {
261280
self.accessList = options.accessList ?? self.accessList
262281
}
263282

264-
public func getOptions() -> TransactionOptions {
265-
var options = TransactionOptions()
266-
options.nonce = .manual(self.nonce)
267-
options.maxPriorityFeePerGas = .manual(self.maxPriorityFeePerGas)
268-
options.maxFeePerGas = .manual(self.maxFeePerGas)
269-
options.gasLimit = .manual(self.gasLimit)
270-
options.value = self.nonce
271-
options.to = self.to
272-
options.accessList = self.accessList
273-
return options
274-
}
275-
276283
public func encode(for type: EncodeType = .transaction) -> Data? {
277284
let fields: [AnyObject]
278285
let list = accessList.map { $0.encodeAsList() as AnyObject }
279286

280287
switch type {
281-
case .transaction: fields = [internalChainID, nonce, maxPriorityFeePerGas, maxFeePerGas, gasLimit, to.addressData, value, data, list, v, r, s] as [AnyObject]
282-
case .signature: fields = [internalChainID, nonce, maxPriorityFeePerGas, maxFeePerGas, gasLimit, to.addressData, value, data, list] as [AnyObject]
288+
case .transaction: fields = [chainID, nonce, maxPriorityFeePerGas, maxFeePerGas, gasLimit, to.addressData, value, data, list, v, r, s] as [AnyObject]
289+
case .signature: fields = [chainID, nonce, maxPriorityFeePerGas, maxFeePerGas, gasLimit, to.addressData, value, data, list] as [AnyObject]
283290
}
284291
guard var result = RLP.encode(fields) else { return nil }
285292
result.insert(UInt8(self.type.rawValue), at: 0)
@@ -297,7 +304,7 @@ extension EIP1559Envelope {
297304
var params = TransactionParameters(from: from?.address.lowercased(), to: toString)
298305
let typeEncoding = String(UInt8(self.type.rawValue), radix: 16).addHexPrefix()
299306
params.type = typeEncoding
300-
let chainEncoding = self.internalChainID.abiEncode(bits: 256)
307+
let chainEncoding = self.chainID.abiEncode(bits: 256)
301308
params.chainID = chainEncoding?.toHexString().addHexPrefix().stripLeadingZeroes()
302309
var accessEncoding: [TransactionParameters.AccessListEntry] = []
303310
for listEntry in self.accessList {

Sources/web3swift/Transaction/EIP2930Envelope.swift

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,7 @@ public struct EIP2930Envelope: EIP2718Envelope {
1313

1414
// common parameters for any transaction
1515
public var nonce: BigUInt = 0
16-
public var chainID: BigUInt? {
17-
get { return internalChainID }
18-
// swiftlint:disable force_unwrapping
19-
set(newID) { if newID != nil { internalChainID = newID! } }
20-
// swiftlint:enable force_unwrapping
21-
}
16+
public var chainID: BigUInt
2217
public var to: EthereumAddress
2318
public var value: BigUInt
2419
public var data: Data
@@ -31,8 +26,6 @@ public struct EIP2930Envelope: EIP2718Envelope {
3126
public var gasLimit: BigUInt = 0
3227
public var accessList: [AccessListEntry] = []
3328

34-
private var internalChainID: BigUInt
35-
3629
// for CustomStringConvertible
3730
public var description: String {
3831
var toReturn = ""
@@ -50,6 +43,33 @@ public struct EIP2930Envelope: EIP2718Envelope {
5043
toReturn += "s: " + String(self.s) + "\n"
5144
return toReturn
5245
}
46+
47+
public var parameters: EthereumParameters {
48+
get {
49+
return EthereumParameters(
50+
type: type,
51+
to: to,
52+
nonce: nonce,
53+
chainID: chainID,
54+
value: value,
55+
data: data,
56+
gasLimit: gasLimit,
57+
gasPrice: gasPrice,
58+
accessList: accessList
59+
)
60+
}
61+
set(val) {
62+
nonce = val.nonce ?? nonce
63+
chainID = val.chainID ?? chainID
64+
to = val.to ?? to
65+
value = val.value ?? value
66+
data = val.data ?? data
67+
gasLimit = val.gasLimit ?? gasLimit
68+
gasPrice = val.gasPrice ?? gasPrice
69+
accessList = val.accessList ?? accessList
70+
}
71+
}
72+
5373
}
5474

5575
extension EIP2930Envelope {
@@ -77,7 +97,7 @@ extension EIP2930Envelope {
7797
guard container.contains(.v), container.contains(.r), container.contains(.s) else { return nil }
7898

7999
// everything we need is present, so we should only have to throw from here
80-
self.internalChainID = try container.decodeHexIfPresent(BigUInt.self, forKey: .chainId) ?? 0
100+
self.chainID = try container.decodeHexIfPresent(BigUInt.self, forKey: .chainId) ?? 0
81101
self.nonce = try container.decodeHex(BigUInt.self, forKey: .nonce)
82102

83103
let list = try? container.decode([AccessListEntry].self, forKey: .accessList)
@@ -141,7 +161,7 @@ extension EIP2930Envelope {
141161
guard let sData = rlpItem[RlpKey.sig_s.rawValue]!.data else { return nil }
142162
// swiftlint:enable force_unwrapping
143163

144-
self.internalChainID = BigUInt(chainData)
164+
self.chainID = BigUInt(chainData)
145165
self.nonce = BigUInt(nonceData)
146166
self.gasPrice = BigUInt(gasPriceData)
147167
self.gasLimit = BigUInt(gasLimitData)
@@ -191,21 +211,19 @@ extension EIP2930Envelope {
191211
}
192212

193213
public init(to: EthereumAddress, nonce: BigUInt? = nil,
194-
chainID: BigUInt? = nil, value: BigUInt? = nil, data: Data,
195214
v: BigUInt = 1, r: BigUInt = 0, s: BigUInt = 0,
196-
options: TransactionOptions? = nil) {
215+
parameters: EthereumParameters? = nil) {
197216
self.to = to
198-
self.nonce = nonce ?? options?.resolveNonce(0) ?? 0
199-
self.internalChainID = chainID ?? 0
200-
self.value = value ?? options?.value ?? 0
201-
self.data = data
217+
self.nonce = nonce ?? parameters?.nonce ?? 0
218+
self.chainID = parameters?.chainID ?? 0
219+
self.value = parameters?.value ?? 0
220+
self.data = parameters?.data ?? Data()
202221
self.v = v
203222
self.r = r
204223
self.s = s
205-
// decode gas options, if present
206-
self.gasPrice = options?.resolveGasPrice(0) ?? 0
207-
self.gasLimit = options?.resolveGasLimit(0) ?? 0
208-
self.accessList = options?.accessList ?? []
224+
self.gasPrice = parameters?.gasPrice ?? 0
225+
self.gasLimit = parameters?.gasLimit ?? 0
226+
self.accessList = parameters?.accessList ?? []
209227
}
210228

211229
// memberwise
@@ -215,7 +233,7 @@ extension EIP2930Envelope {
215233
v: BigUInt = 1, r: BigUInt = 0, s: BigUInt = 0) {
216234
self.to = to
217235
self.nonce = nonce
218-
self.internalChainID = chainID
236+
self.chainID = chainID
219237
self.value = value
220238
self.data = data
221239
self.gasPrice = gasPrice
@@ -238,24 +256,13 @@ extension EIP2930Envelope {
238256
// swiftlint:enable force_unwrapping
239257
}
240258

241-
public func getOptions() -> TransactionOptions {
242-
var options = TransactionOptions()
243-
options.nonce = .manual(self.nonce)
244-
options.gasPrice = .manual(self.gasPrice)
245-
options.gasLimit = .manual(self.gasLimit)
246-
options.value = self.nonce
247-
options.to = self.to
248-
options.accessList = self.accessList
249-
return options
250-
}
251-
252259
public func encode(for type: EncodeType = .transaction) -> Data? {
253260
let fields: [AnyObject]
254261
let list = accessList.map { $0.encodeAsList() as AnyObject }
255262

256263
switch type {
257-
case .transaction: fields = [internalChainID, nonce, gasPrice, gasLimit, to.addressData, value, data, list, v, r, s] as [AnyObject]
258-
case .signature: fields = [internalChainID, nonce, gasPrice, gasLimit, to.addressData, value, data, list] as [AnyObject]
264+
case .transaction: fields = [chainID, nonce, gasPrice, gasLimit, to.addressData, value, data, list, v, r, s] as [AnyObject]
265+
case .signature: fields = [chainID, nonce, gasPrice, gasLimit, to.addressData, value, data, list] as [AnyObject]
259266
}
260267
guard var result = RLP.encode(fields) else { return nil }
261268
result.insert(UInt8(self.type.rawValue), at: 0)
@@ -273,7 +280,7 @@ extension EIP2930Envelope {
273280
var params = TransactionParameters(from: from?.address.lowercased(), to: toString)
274281
let typeEncoding = String(UInt8(self.type.rawValue), radix: 16).addHexPrefix()
275282
params.type = typeEncoding
276-
let chainEncoding = self.internalChainID.abiEncode(bits: 256)
283+
let chainEncoding = self.chainID.abiEncode(bits: 256)
277284
params.chainID = chainEncoding?.toHexString().addHexPrefix().stripLeadingZeroes()
278285
var accessEncoding: [TransactionParameters.AccessListEntry] = []
279286
for listEntry in self.accessList {

0 commit comments

Comments
 (0)