@@ -8,18 +8,40 @@ import Foundation
8
8
import BigInt
9
9
10
10
public struct EthereumTransaction : CustomStringConvertible {
11
+ // FIXME: Add Type value https://blog.mycrypto.com/new-transaction-types-on-ethereum
11
12
public var nonce : BigUInt
12
- public var gasPrice : BigUInt = BigUInt ( 0 )
13
- public var gasLimit : BigUInt = BigUInt ( 0 )
13
+ public var gasPrice : BigUInt = 0
14
+ public var gasLimit : BigUInt = 0
15
+
16
+ // MARK: - EIP-1559
17
+ /// Value of the tip to the miner for transaction processing.
18
+ ///
19
+ /// Full amount of this variable goes to a miner.
20
+ public var maxPriorityFeePerGas : BigUInt = 0
21
+
22
+ /// Value of the fee for one gas unit
23
+ ///
24
+ /// This value should be greather than sum of:
25
+ /// - `Block.nextBlockBaseFeePerGas` - baseFee which will burnt during the transaction processing
26
+ /// - `self.maxPriorityFeePerGas` - explicit amount of a tip to the miner of the given block which will include this transaction
27
+ ///
28
+ /// If amount of this will be **greather** than sum of `Block.baseFeePerGas` and `maxPriorityFeePerGas`
29
+ /// all exceed funds will be returned to the sender.
30
+ ///
31
+ /// If amount of this will be **lower** than sum of `Block.baseFeePerGas` and `maxPriorityFeePerGas`
32
+ /// miner will recieve amount of the follow equation: `maxFeePerGas - Block.baseFeePerGas` if any,
33
+ /// where Block is a block to which transaction will be included.
34
+ public var maxFeePerGas : BigUInt = 0
35
+
14
36
// The destination address of the message, left undefined for a contract-creation transaction.
15
37
public var to : EthereumAddress
16
38
// (optional) The value transferred for the transaction in wei, also the endowment if it’s a contract-creation transaction.
17
39
// TODO - split EthereumTransaction to two classes: with optional and required value property, depends on type of transaction
18
40
public var value : BigUInt ?
19
41
public var data : Data
20
- public var v : BigUInt = BigUInt ( 1 )
21
- public var r : BigUInt = BigUInt ( 0 )
22
- public var s : BigUInt = BigUInt ( 0 )
42
+ public var v : BigUInt = 1
43
+ public var r : BigUInt = 0
44
+ public var s : BigUInt = 0
23
45
var chainID : BigUInt ? = nil
24
46
25
47
public var inferedChainID : BigUInt ? {
@@ -33,93 +55,69 @@ public struct EthereumTransaction: CustomStringConvertible {
33
55
}
34
56
}
35
57
}
36
-
37
- public var intrinsicChainID : BigUInt ? {
38
- get {
39
- return self . chainID
40
- }
41
- }
42
-
58
+
59
+ public var intrinsicChainID : BigUInt ? { chainID }
60
+
43
61
public mutating func UNSAFE_setChainID( _ chainID: BigUInt ? ) {
44
62
self . chainID = chainID
45
63
}
46
64
47
65
public var hash : Data ? {
48
66
var encoded : Data
49
67
let inferedChainID = self . inferedChainID
50
- if inferedChainID != nil {
51
- guard let enc = self . self. encode ( forSignature: false , chainID: inferedChainID) else { return nil }
68
+ if let inferedChainID = inferedChainID {
69
+ guard let enc = self . self. encode ( forSignature: false , chainID: inferedChainID) else { return nil }
52
70
encoded = enc
53
71
} else {
54
- guard let enc = self . self. encode ( forSignature: false , chainID: self . chainID) else { return nil }
72
+ guard let enc = self . self. encode ( forSignature: false , chainID: chainID) else { return nil }
55
73
encoded = enc
56
74
}
57
75
let hash = encoded. sha3 ( . keccak256)
58
76
return hash
59
77
}
60
-
61
- public init ( gasPrice: BigUInt , gasLimit: BigUInt , to: EthereumAddress , value: BigUInt , data: Data ) {
62
- self . nonce = BigUInt ( 0 )
63
- self . gasPrice = gasPrice
64
- self . gasLimit = gasLimit
65
- self . value = value
66
- self . data = data
67
- self . to = to
68
- }
69
-
70
- public init ( nonce: BigUInt , gasPrice: BigUInt , gasLimit: BigUInt , to: EthereumAddress , value: BigUInt , data: Data , v: BigUInt , r: BigUInt , s: BigUInt ) {
71
- self . nonce = nonce
72
- self . gasPrice = gasPrice
73
- self . gasLimit = gasLimit
74
- self . to = to
75
- self . value = value
76
- self . data = data
77
- self . v = v
78
- self . r = r
79
- self . s = s
80
- }
81
-
78
+
82
79
public var description : String {
83
- get {
84
- var toReturn = " "
85
- toReturn = toReturn + " Transaction " + " \n "
86
- toReturn = toReturn + " Nonce: " + String( self . nonce) + " \n "
87
- toReturn = toReturn + " Gas price: " + String( self . gasPrice) + " \n "
88
- toReturn = toReturn + " Gas limit: " + String( describing: self . gasLimit) + " \n "
89
- toReturn = toReturn + " To: " + self . to. address + " \n "
90
- toReturn = toReturn + " Value: " + String( self . value ?? " nil " ) + " \n "
91
- toReturn = toReturn + " Data: " + self . data. toHexString ( ) . addHexPrefix ( ) . lowercased ( ) + " \n "
92
- toReturn = toReturn + " v: " + String( self . v) + " \n "
93
- toReturn = toReturn + " r: " + String( self . r) + " \n "
94
- toReturn = toReturn + " s: " + String( self . s) + " \n "
95
- toReturn = toReturn + " Intrinsic chainID: " + String( describing: self . chainID) + " \n "
96
- toReturn = toReturn + " Infered chainID: " + String( describing: self . inferedChainID) + " \n "
97
- toReturn = toReturn + " sender: " + String( describing: self . sender? . address) + " \n "
98
- toReturn = toReturn + " hash: " + String( describing: self . hash? . toHexString ( ) . addHexPrefix ( ) ) + " \n "
99
- return toReturn
100
- }
101
-
80
+ var toReturn = " "
81
+ toReturn += " Transaction " + " \n "
82
+ toReturn += " Nonce: " + String( self . nonce) + " \n "
83
+ toReturn += " Gas price: " + String( self . gasPrice) + " \n "
84
+ toReturn += " Gas limit: " + String( describing: self . gasLimit) + " \n "
85
+ toReturn += " Max priority fee per gas: " + String( describing: self . maxPriorityFeePerGas)
86
+ toReturn += " Max fee per gas: " + String( describing: maxFeePerGas)
87
+ toReturn += " To: " + self . to. address + " \n "
88
+ toReturn += " Value: " + String( self . value ?? " nil " ) + " \n "
89
+ toReturn += " Data: " + self . data. toHexString ( ) . addHexPrefix ( ) . lowercased ( ) + " \n "
90
+ toReturn += " v: " + String( self . v) + " \n "
91
+ toReturn += " r: " + String( self . r) + " \n "
92
+ toReturn += " s: " + String( self . s) + " \n "
93
+ toReturn += " Intrinsic chainID: " + String( describing: self . chainID) + " \n "
94
+ toReturn += " Infered chainID: " + String( describing: self . inferedChainID) + " \n "
95
+ toReturn += " sender: " + String( describing: self . sender? . address) + " \n "
96
+ toReturn += " hash: " + String( describing: self . hash? . toHexString ( ) . addHexPrefix ( ) ) + " \n "
97
+ return toReturn
102
98
}
99
+
103
100
public var sender : EthereumAddress ? {
104
- get {
105
- guard let publicKey = self . recoverPublicKey ( ) else { return nil }
106
- return Web3 . Utils. publicToAddress ( publicKey)
107
- }
101
+ guard let publicKey = self . recoverPublicKey ( ) else { return nil }
102
+ return Web3 . Utils. publicToAddress ( publicKey)
108
103
}
109
104
110
105
public func recoverPublicKey( ) -> Data ? {
111
- if ( self . r == BigUInt ( 0 ) && self . s == BigUInt ( 0 ) ) {
112
- return nil
113
- }
114
- var normalizedV : BigUInt = BigUInt ( 27 )
106
+ // FIXME: AND not OR condition
107
+ guard r != 0 , s != 0 else { return nil }
108
+ // if (self.r == 0 && self.s == 0) {
109
+ // return nil
110
+ // }
111
+ var normalizedV : BigUInt = 27
115
112
let inferedChainID = self . inferedChainID
116
- var d = BigUInt ( 0 )
113
+ var d : BigUInt = 0
114
+
117
115
if self . v >= 35 && self . v <= 38 {
118
- d = BigUInt ( 35 )
116
+ d = 35
119
117
} else if self . v >= 31 && self . v <= 34 {
120
- d = BigUInt ( 31 )
118
+ d = 31
121
119
} else if self . v >= 27 && self . v <= 30 {
122
- d = BigUInt ( 27 )
120
+ d = 27
123
121
}
124
122
if let testID = self . chainID, testID != BigUInt ( 0 ) && self . v >= ( d + testID + testID) {
125
123
normalizedV = self . v - d - testID - testID
@@ -146,22 +144,16 @@ public struct EthereumTransaction: CustomStringConvertible {
146
144
}
147
145
148
146
public var txhash : String ? {
149
- get {
150
- guard self . sender != nil else { return nil }
151
- guard let hash = self . hash else { return nil }
152
- let txid = hash. toHexString ( ) . addHexPrefix ( ) . lowercased ( )
153
- return txid
154
- }
155
- }
156
-
157
- public var txid : String ? {
158
- get {
159
- return self . txhash
160
- }
147
+ guard sender != nil else { return nil }
148
+ guard let hash = hash else { return nil }
149
+ let txid = hash. toHexString ( ) . addHexPrefix ( ) . lowercased ( )
150
+ return txid
161
151
}
162
-
152
+
153
+ public var txid : String ? { txhash }
154
+
163
155
public func encode( forSignature: Bool = false , chainID: BigUInt ? = nil ) -> Data ? {
164
- if ( forSignature) {
156
+ if forSignature {
165
157
if chainID != nil {
166
158
let fields = [ self . nonce, self . gasPrice, self . gasLimit, self . to. addressData, self . value!, self . data, chainID!, BigUInt ( 0 ) , BigUInt ( 0 ) ] as [ AnyObject ]
167
159
return RLP . encode ( fields)
@@ -286,12 +278,12 @@ public struct EthereumTransaction: CustomStringConvertible {
286
278
}
287
279
}
288
280
289
- public extension EthereumTransaction {
281
+ extension EthereumTransaction {
290
282
init ( to: EthereumAddress , data: Data , options: TransactionOptions ) {
291
283
let defaults = TransactionOptions . defaultOptions
292
284
let merged = defaults. merge ( options)
293
- self . nonce = BigUInt ( 0 )
294
-
285
+ nonce = 0
286
+
295
287
if let gP = merged. gasPrice {
296
288
switch gP {
297
289
case . manual( let value) :
@@ -318,6 +310,18 @@ public extension EthereumTransaction {
318
310
self . data = data
319
311
}
320
312
313
+ }
314
+
315
+ public extension EthereumTransaction {
316
+ init ( gasPrice: BigUInt , gasLimit: BigUInt , to: EthereumAddress , value: BigUInt , data: Data ) {
317
+ self . nonce = BigUInt ( 0 )
318
+ self . gasPrice = gasPrice
319
+ self . gasLimit = gasLimit
320
+ self . value = value
321
+ self . data = data
322
+ self . to = to
323
+ }
324
+
321
325
func mergedWithOptions( _ options: TransactionOptions ) -> EthereumTransaction {
322
326
var tx = self
323
327
0 commit comments