Skip to content

Commit

Permalink
Merge pull request #3 from BaldyAsh/ERC721fix
Browse files Browse the repository at this point in the history
Fixed erc721 precompiled contract
  • Loading branch information
TonioMacaronio authored Dec 14, 2018
2 parents dbfecb1 + 0f144dd commit 649b45a
Showing 1 changed file with 127 additions and 62 deletions.
189 changes: 127 additions & 62 deletions web3swift/PrecompiledContracts/ERC721/Web3+ERC721.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,52 @@ import BigInt
import PromiseKit
import EthereumAddress

protocol IERC721 {

func getBalance(account: EthereumAddress) throws -> BigUInt

func getOwner(tokenId: BigUInt) throws -> EthereumAddress

func transferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, tokenId: BigUInt) throws -> WriteTransaction

func transfer(from: EthereumAddress, to: EthereumAddress, tokenId: BigUInt) throws -> WriteTransaction

func approve(from: EthereumAddress, approved: EthereumAddress, tokenId: BigUInt) throws -> WriteTransaction

func setApprovalForAll(from: EthereumAddress, operator user: EthereumAddress, approved: Bool) throws -> WriteTransaction

func getApproved(tokenId: BigUInt) throws -> EthereumAddress

func isApprovedForAll(owner: EthereumAddress, operator user: EthereumAddress) throws -> Bool
}

protocol IERC721Metadata {

func name() throws -> String

func symbol() throws -> String

func tokenURI(tokenId: BigUInt) throws -> String

}

protocol IERC721Enumerable {

func totalSupply() throws -> BigUInt

func tokenByIndex(index: BigUInt) throws -> BigUInt

func tokenOfOwnerByIndex(owner: EthereumAddress, index: BigUInt) throws -> BigUInt
}

// This namespace contains functions to work with ERC721 tokens.
// can be imperatively read and saved
public class ERC721 {
public class ERC721: IERC721 {

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

private var _name: String? = nil
private var _symbol: String? = nil
private var _tokenId: BigUInt? = nil
private var _tokenURI: String? = nil
private var _hasReadProperties: Bool = false

public var transactionOptions: TransactionOptions
Expand All @@ -42,22 +77,6 @@ public class ERC721 {
self.transactionOptions = mergedOptions
}

public var name: String {
self.readProperties()
if self._name != nil {
return self._name!
}
return ""
}

public var symbol: String {
self.readProperties()
if self._symbol != nil {
return self._symbol!
}
return ""
}

public var tokenId: BigUInt {
self.readProperties()
if self._tokenId != nil {
Expand All @@ -66,14 +85,6 @@ public class ERC721 {
return 0
}

public var tokenURI: String {
self.readProperties()
if self._tokenURI != nil {
return self._tokenURI!
}
return ""
}

public func readProperties() {
if self._hasReadProperties {
return
Expand All @@ -82,33 +93,16 @@ public class ERC721 {
guard contract.contract.address != nil else {return}
var transactionOptions = TransactionOptions.defaultOptions
transactionOptions.callOnBlock = .latest
guard let namePromise = contract.read("name", parameters: [] as [AnyObject], extraData: Data(), transactionOptions: transactionOptions)?.callPromise() else {return}

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

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

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

let allPromises = [namePromise, symbolPromise, tokenIdPromise, tokenURIpromise]
let allPromises = [tokenIdPromise]
let queue = self.web3.requestDispatcher.queue
when(resolved: allPromises).map(on: queue) { (resolvedPromises) -> Void in
guard case .fulfilled(let nameResult) = resolvedPromises[0] else {return}
guard let name = nameResult["0"] as? String else {return}
self._name = name

guard case .fulfilled(let symbolResult) = resolvedPromises[1] else {return}
guard let symbol = symbolResult["0"] as? String else {return}
self._symbol = symbol

guard case .fulfilled(let tokenIdResult) = resolvedPromises[2] else {return}
guard case .fulfilled(let tokenIdResult) = resolvedPromises[0] else {return}
guard let tokenId = tokenIdResult["0"] as? BigUInt else {return}
self._tokenId = tokenId

guard case .fulfilled(let tokenURIresult) = resolvedPromises[3] else {return}
guard let uri = tokenURIresult["0"] as? String else {return}
self._tokenURI = uri

self._hasReadProperties = true
}.wait()
}
Expand All @@ -122,7 +116,7 @@ public class ERC721 {
return res
}

public func getOwner(tokenId: BigUInt) throws -> EthereumAddress{
public func getOwner(tokenId: BigUInt) throws -> EthereumAddress {
let contract = self.contract
var transactionOptions = TransactionOptions()
transactionOptions.callOnBlock = .latest
Expand All @@ -140,6 +134,66 @@ public class ERC721 {
return res
}

public func transfer(from: EthereumAddress, to: EthereumAddress, tokenId: BigUInt) throws -> WriteTransaction {
let contract = self.contract
var basicOptions = TransactionOptions()
basicOptions.from = from
basicOptions.to = self.address

let tx = contract.write("transfer", parameters: [to, tokenId] as [AnyObject], transactionOptions: basicOptions)!
return tx
}

public func transferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, tokenId: BigUInt) throws -> WriteTransaction {
let contract = self.contract
var basicOptions = TransactionOptions()
basicOptions.from = from
basicOptions.to = self.address

let tx = contract.write("transferFrom", parameters: [originalOwner, to, tokenId] as [AnyObject], transactionOptions: basicOptions)!
return tx
}

public func approve(from: EthereumAddress, approved: EthereumAddress, tokenId: BigUInt) throws -> WriteTransaction {
let contract = self.contract
var basicOptions = TransactionOptions()
basicOptions.from = from

let tx = contract.write("approve", parameters: [approved, tokenId] as [AnyObject], transactionOptions: basicOptions)!
return tx
}

public func setApprovalForAll(from: EthereumAddress, operator user: EthereumAddress, approved: Bool) throws -> WriteTransaction {
let contract = self.contract
var basicOptions = TransactionOptions()
basicOptions.from = from

let tx = contract.write("setApprovalForAll", parameters: [user, approved] as [AnyObject], transactionOptions: basicOptions)!
return tx
}

public func isApprovedForAll(owner: EthereumAddress, operator user: EthereumAddress) throws -> Bool {
let contract = self.contract
var basicOptions = TransactionOptions()
basicOptions.callOnBlock = .latest
let result = try contract.read("isApprovedForAll", parameters: [owner, user] as [AnyObject], extraData: Data(), transactionOptions: self.transactionOptions)!.call(transactionOptions: transactionOptions)
guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")}
return res
}

}

extension ERC721: IERC721Enumerable {

public func totalSupply() throws -> BigUInt {
let contract = self.contract
var transactionOptions = TransactionOptions()
transactionOptions.callOnBlock = .latest
let result = try contract.read("totalSupply", parameters: [AnyObject](), extraData: Data(), transactionOptions: self.transactionOptions)!.call(transactionOptions: transactionOptions)
guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")}
return res
}

public func tokenByIndex(index: BigUInt) throws -> BigUInt {
let contract = self.contract
var transactionOptions = TransactionOptions()
Expand All @@ -158,24 +212,35 @@ public class ERC721 {
return res
}

public func transfer(from: EthereumAddress, to: EthereumAddress, tokenId: BigUInt) throws -> WriteTransaction {
}

extension ERC721: IERC721Metadata {

public func name() throws -> String {
let contract = self.contract
var basicOptions = TransactionOptions()
basicOptions.from = from
basicOptions.to = self.address

let tx = contract.write("transfer", parameters: [to, tokenId] as [AnyObject], transactionOptions: basicOptions)!
return tx
var transactionOptions = TransactionOptions()
transactionOptions.callOnBlock = .latest
let result = try contract.read("name", parameters: [AnyObject](), extraData: Data(), transactionOptions: self.transactionOptions)!.call(transactionOptions: transactionOptions)
guard let res = result["0"] as? String else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")}
return res
}

public func transferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, tokenId: BigUInt) throws -> WriteTransaction {
public func symbol() throws -> String {
let contract = self.contract
var basicOptions = TransactionOptions()
basicOptions.from = from
basicOptions.to = self.address

let tx = contract.write("transferFrom", parameters: [originalOwner, to, tokenId] as [AnyObject], transactionOptions: basicOptions)!
return tx
var transactionOptions = TransactionOptions()
transactionOptions.callOnBlock = .latest
let result = try contract.read("symbol", parameters: [AnyObject](), extraData: Data(), transactionOptions: self.transactionOptions)!.call(transactionOptions: transactionOptions)
guard let res = result["0"] as? String else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")}
return res
}

public func tokenURI(tokenId: BigUInt) throws -> String {
let contract = self.contract
var transactionOptions = TransactionOptions()
transactionOptions.callOnBlock = .latest
let result = try contract.read("tokenId", parameters: [tokenId] as [AnyObject], extraData: Data(), transactionOptions: self.transactionOptions)!.call(transactionOptions: transactionOptions)
guard let res = result["0"] as? String else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")}
return res
}

}

0 comments on commit 649b45a

Please sign in to comment.