Skip to content

Commit 649b45a

Browse files
Merge pull request #3 from BaldyAsh/ERC721fix
Fixed erc721 precompiled contract
2 parents dbfecb1 + 0f144dd commit 649b45a

File tree

1 file changed

+127
-62
lines changed

1 file changed

+127
-62
lines changed

web3swift/PrecompiledContracts/ERC721/Web3+ERC721.swift

Lines changed: 127 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,52 @@ import BigInt
99
import PromiseKit
1010
import EthereumAddress
1111

12+
protocol IERC721 {
13+
14+
func getBalance(account: EthereumAddress) throws -> BigUInt
15+
16+
func getOwner(tokenId: BigUInt) throws -> EthereumAddress
17+
18+
func transferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, tokenId: BigUInt) throws -> WriteTransaction
19+
20+
func transfer(from: EthereumAddress, to: EthereumAddress, tokenId: BigUInt) throws -> WriteTransaction
21+
22+
func approve(from: EthereumAddress, approved: EthereumAddress, tokenId: BigUInt) throws -> WriteTransaction
23+
24+
func setApprovalForAll(from: EthereumAddress, operator user: EthereumAddress, approved: Bool) throws -> WriteTransaction
25+
26+
func getApproved(tokenId: BigUInt) throws -> EthereumAddress
27+
28+
func isApprovedForAll(owner: EthereumAddress, operator user: EthereumAddress) throws -> Bool
29+
}
30+
31+
protocol IERC721Metadata {
32+
33+
func name() throws -> String
34+
35+
func symbol() throws -> String
36+
37+
func tokenURI(tokenId: BigUInt) throws -> String
38+
39+
}
40+
41+
protocol IERC721Enumerable {
42+
43+
func totalSupply() throws -> BigUInt
44+
45+
func tokenByIndex(index: BigUInt) throws -> BigUInt
46+
47+
func tokenOfOwnerByIndex(owner: EthereumAddress, index: BigUInt) throws -> BigUInt
48+
}
49+
1250
// This namespace contains functions to work with ERC721 tokens.
1351
// can be imperatively read and saved
14-
public class ERC721 {
52+
public class ERC721: IERC721 {
1553

1654
@available(*, deprecated, renamed: "transactionOptions")
1755
public var options: Web3Options = .init()
1856

19-
private var _name: String? = nil
20-
private var _symbol: String? = nil
2157
private var _tokenId: BigUInt? = nil
22-
private var _tokenURI: String? = nil
2358
private var _hasReadProperties: Bool = false
2459

2560
public var transactionOptions: TransactionOptions
@@ -42,22 +77,6 @@ public class ERC721 {
4277
self.transactionOptions = mergedOptions
4378
}
4479

45-
public var name: String {
46-
self.readProperties()
47-
if self._name != nil {
48-
return self._name!
49-
}
50-
return ""
51-
}
52-
53-
public var symbol: String {
54-
self.readProperties()
55-
if self._symbol != nil {
56-
return self._symbol!
57-
}
58-
return ""
59-
}
60-
6180
public var tokenId: BigUInt {
6281
self.readProperties()
6382
if self._tokenId != nil {
@@ -66,14 +85,6 @@ public class ERC721 {
6685
return 0
6786
}
6887

69-
public var tokenURI: String {
70-
self.readProperties()
71-
if self._tokenURI != nil {
72-
return self._tokenURI!
73-
}
74-
return ""
75-
}
76-
7788
public func readProperties() {
7889
if self._hasReadProperties {
7990
return
@@ -82,33 +93,16 @@ public class ERC721 {
8293
guard contract.contract.address != nil else {return}
8394
var transactionOptions = TransactionOptions.defaultOptions
8495
transactionOptions.callOnBlock = .latest
85-
guard let namePromise = contract.read("name", parameters: [] as [AnyObject], extraData: Data(), transactionOptions: transactionOptions)?.callPromise() else {return}
86-
87-
guard let symbolPromise = contract.read("symbol", parameters: [] as [AnyObject], extraData: Data(), transactionOptions: transactionOptions)?.callPromise() else {return}
8896

8997
guard let tokenIdPromise = contract.read("tokenId", parameters: [] as [AnyObject], extraData: Data(), transactionOptions: transactionOptions)?.callPromise() else {return}
9098

91-
guard let tokenURIpromise = contract.read("tokenURI", parameters: [] as [AnyObject], extraData: Data(), transactionOptions: transactionOptions)?.callPromise() else {return}
92-
93-
let allPromises = [namePromise, symbolPromise, tokenIdPromise, tokenURIpromise]
99+
let allPromises = [tokenIdPromise]
94100
let queue = self.web3.requestDispatcher.queue
95101
when(resolved: allPromises).map(on: queue) { (resolvedPromises) -> Void in
96-
guard case .fulfilled(let nameResult) = resolvedPromises[0] else {return}
97-
guard let name = nameResult["0"] as? String else {return}
98-
self._name = name
99-
100-
guard case .fulfilled(let symbolResult) = resolvedPromises[1] else {return}
101-
guard let symbol = symbolResult["0"] as? String else {return}
102-
self._symbol = symbol
103-
104-
guard case .fulfilled(let tokenIdResult) = resolvedPromises[2] else {return}
102+
guard case .fulfilled(let tokenIdResult) = resolvedPromises[0] else {return}
105103
guard let tokenId = tokenIdResult["0"] as? BigUInt else {return}
106104
self._tokenId = tokenId
107105

108-
guard case .fulfilled(let tokenURIresult) = resolvedPromises[3] else {return}
109-
guard let uri = tokenURIresult["0"] as? String else {return}
110-
self._tokenURI = uri
111-
112106
self._hasReadProperties = true
113107
}.wait()
114108
}
@@ -122,7 +116,7 @@ public class ERC721 {
122116
return res
123117
}
124118

125-
public func getOwner(tokenId: BigUInt) throws -> EthereumAddress{
119+
public func getOwner(tokenId: BigUInt) throws -> EthereumAddress {
126120
let contract = self.contract
127121
var transactionOptions = TransactionOptions()
128122
transactionOptions.callOnBlock = .latest
@@ -140,6 +134,66 @@ public class ERC721 {
140134
return res
141135
}
142136

137+
public func transfer(from: EthereumAddress, to: EthereumAddress, tokenId: BigUInt) throws -> WriteTransaction {
138+
let contract = self.contract
139+
var basicOptions = TransactionOptions()
140+
basicOptions.from = from
141+
basicOptions.to = self.address
142+
143+
let tx = contract.write("transfer", parameters: [to, tokenId] as [AnyObject], transactionOptions: basicOptions)!
144+
return tx
145+
}
146+
147+
public func transferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, tokenId: BigUInt) throws -> WriteTransaction {
148+
let contract = self.contract
149+
var basicOptions = TransactionOptions()
150+
basicOptions.from = from
151+
basicOptions.to = self.address
152+
153+
let tx = contract.write("transferFrom", parameters: [originalOwner, to, tokenId] as [AnyObject], transactionOptions: basicOptions)!
154+
return tx
155+
}
156+
157+
public func approve(from: EthereumAddress, approved: EthereumAddress, tokenId: BigUInt) throws -> WriteTransaction {
158+
let contract = self.contract
159+
var basicOptions = TransactionOptions()
160+
basicOptions.from = from
161+
162+
let tx = contract.write("approve", parameters: [approved, tokenId] as [AnyObject], transactionOptions: basicOptions)!
163+
return tx
164+
}
165+
166+
public func setApprovalForAll(from: EthereumAddress, operator user: EthereumAddress, approved: Bool) throws -> WriteTransaction {
167+
let contract = self.contract
168+
var basicOptions = TransactionOptions()
169+
basicOptions.from = from
170+
171+
let tx = contract.write("setApprovalForAll", parameters: [user, approved] as [AnyObject], transactionOptions: basicOptions)!
172+
return tx
173+
}
174+
175+
public func isApprovedForAll(owner: EthereumAddress, operator user: EthereumAddress) throws -> Bool {
176+
let contract = self.contract
177+
var basicOptions = TransactionOptions()
178+
basicOptions.callOnBlock = .latest
179+
let result = try contract.read("isApprovedForAll", parameters: [owner, user] as [AnyObject], extraData: Data(), transactionOptions: self.transactionOptions)!.call(transactionOptions: transactionOptions)
180+
guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")}
181+
return res
182+
}
183+
184+
}
185+
186+
extension ERC721: IERC721Enumerable {
187+
188+
public func totalSupply() throws -> BigUInt {
189+
let contract = self.contract
190+
var transactionOptions = TransactionOptions()
191+
transactionOptions.callOnBlock = .latest
192+
let result = try contract.read("totalSupply", parameters: [AnyObject](), extraData: Data(), transactionOptions: self.transactionOptions)!.call(transactionOptions: transactionOptions)
193+
guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")}
194+
return res
195+
}
196+
143197
public func tokenByIndex(index: BigUInt) throws -> BigUInt {
144198
let contract = self.contract
145199
var transactionOptions = TransactionOptions()
@@ -158,24 +212,35 @@ public class ERC721 {
158212
return res
159213
}
160214

161-
public func transfer(from: EthereumAddress, to: EthereumAddress, tokenId: BigUInt) throws -> WriteTransaction {
215+
}
216+
217+
extension ERC721: IERC721Metadata {
218+
219+
public func name() throws -> String {
162220
let contract = self.contract
163-
var basicOptions = TransactionOptions()
164-
basicOptions.from = from
165-
basicOptions.to = self.address
166-
167-
let tx = contract.write("transfer", parameters: [to, tokenId] as [AnyObject], transactionOptions: basicOptions)!
168-
return tx
221+
var transactionOptions = TransactionOptions()
222+
transactionOptions.callOnBlock = .latest
223+
let result = try contract.read("name", parameters: [AnyObject](), extraData: Data(), transactionOptions: self.transactionOptions)!.call(transactionOptions: transactionOptions)
224+
guard let res = result["0"] as? String else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")}
225+
return res
169226
}
170227

171-
public func transferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, tokenId: BigUInt) throws -> WriteTransaction {
228+
public func symbol() throws -> String {
172229
let contract = self.contract
173-
var basicOptions = TransactionOptions()
174-
basicOptions.from = from
175-
basicOptions.to = self.address
176-
177-
let tx = contract.write("transferFrom", parameters: [originalOwner, to, tokenId] as [AnyObject], transactionOptions: basicOptions)!
178-
return tx
230+
var transactionOptions = TransactionOptions()
231+
transactionOptions.callOnBlock = .latest
232+
let result = try contract.read("symbol", parameters: [AnyObject](), extraData: Data(), transactionOptions: self.transactionOptions)!.call(transactionOptions: transactionOptions)
233+
guard let res = result["0"] as? String else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")}
234+
return res
235+
}
236+
237+
public func tokenURI(tokenId: BigUInt) throws -> String {
238+
let contract = self.contract
239+
var transactionOptions = TransactionOptions()
240+
transactionOptions.callOnBlock = .latest
241+
let result = try contract.read("tokenId", parameters: [tokenId] as [AnyObject], extraData: Data(), transactionOptions: self.transactionOptions)!.call(transactionOptions: transactionOptions)
242+
guard let res = result["0"] as? String else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")}
243+
return res
179244
}
180245

181246
}

0 commit comments

Comments
 (0)