Created
May 14, 2018 19:30
-
-
Save koraykoska/c2db36fce19b821221b3f8fdb7bae7da to your computer and use it in GitHub Desktop.
Web3 Swift ERC20 helper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Web3 | |
struct ERC20 { | |
let address: EthereumAddress | |
let reading: Reading | |
let writing: Writing | |
init(contractAddress: EthereumAddress) { | |
self.address = contractAddress | |
self.reading = Reading(contractAddress: contractAddress) | |
self.writing = Writing(contractAddress: contractAddress) | |
} | |
struct Reading { | |
let address: EthereumAddress | |
init(contractAddress: EthereumAddress) { | |
self.address = contractAddress | |
} | |
func name() -> EthereumCall { | |
let data = EthereumData(bytes: [0x06, 0xfd, 0xde, 0x03]) | |
return EthereumCall(to: address, data: data) | |
} | |
func symbol() -> EthereumCall { | |
let data = EthereumData(bytes: [0x95, 0xd8, 0x9b, 0x41]) | |
return EthereumCall(to: address, data: data) | |
} | |
func decimals() -> EthereumCall { | |
let data = EthereumData(bytes: [0x31, 0x3c, 0xe5, 0x67]) | |
return EthereumCall(to: address, data: data) | |
} | |
func totalSupply() -> EthereumCall { | |
let data = EthereumData(bytes: [0x18, 0x16, 0x0d, 0xdd]) | |
return EthereumCall(to: address, data: data) | |
} | |
func balanceOf(owner: EthereumAddress) -> EthereumCall { | |
var bytes: [UInt8] = [0x70, 0xa0, 0x82, 0x31] | |
bytes.append(contentsOf: owner.rawAddress.leftPad(with: 0, multipleOf: 32)) | |
let data = EthereumData(bytes: bytes) | |
return EthereumCall(to: address, data: data) | |
} | |
func allowance(owner: EthereumAddress, spender: EthereumAddress) -> EthereumCall { | |
var bytes: [UInt8] = [0xdd, 0x62, 0xed, 0x3e] | |
bytes.append(contentsOf: owner.rawAddress.leftPad(with: 0, multipleOf: 32)) | |
bytes.append(contentsOf: spender.rawAddress.leftPad(with: 0, multipleOf: 32)) | |
let data = EthereumData(bytes: bytes) | |
return EthereumCall(to: self.address, data: data) | |
} | |
} | |
struct Writing { | |
let address: EthereumAddress | |
init(contractAddress: EthereumAddress) { | |
self.address = contractAddress | |
} | |
func transfer( | |
nonce: EthereumQuantity, | |
gasPrice: EthereumQuantity, | |
gasLimit: EthereumQuantity, | |
to: EthereumAddress, | |
value: EthereumQuantity, | |
chainId: EthereumQuantity | |
) -> EthereumTransaction { | |
var bytes: [UInt8] = [0xa9, 0x05, 0x9c, 0xbb] | |
bytes.append(contentsOf: to.rawAddress.leftPad(with: 0, multipleOf: 32)) | |
bytes.append(contentsOf: value.quantity.makeBytes().leftPad(with: 0, to: 32)) | |
let data = EthereumData(bytes: bytes) | |
let tx = EthereumTransaction(nonce: nonce, gasPrice: gasPrice, gasLimit: gasLimit, to: address, value: 0, data: data, chainId: chainId) | |
return tx | |
} | |
func transferFrom( | |
nonce: EthereumQuantity, | |
gasPrice: EthereumQuantity, | |
gasLimit: EthereumQuantity, | |
from: EthereumAddress, | |
to: EthereumAddress, | |
value: EthereumQuantity, | |
chainId: EthereumQuantity | |
) -> EthereumTransaction { | |
var bytes: [UInt8] = [0x23, 0xb8, 0x72, 0xdd] | |
bytes.append(contentsOf: from.rawAddress.leftPad(with: 0, multipleOf: 32)) | |
bytes.append(contentsOf: to.rawAddress.leftPad(with: 0, multipleOf: 32)) | |
bytes.append(contentsOf: value.quantity.makeBytes().leftPad(with: 0, to: 32)) | |
let data = EthereumData(bytes: bytes) | |
let tx = EthereumTransaction(nonce: nonce, gasPrice: gasPrice, gasLimit: gasLimit, to: address, value: 0, data: data, chainId: chainId) | |
return tx | |
} | |
func approve( | |
nonce: EthereumQuantity, | |
gasPrice: EthereumQuantity, | |
gasLimit: EthereumQuantity, | |
spender: EthereumAddress, | |
value: EthereumQuantity, | |
chainId: EthereumQuantity | |
) -> EthereumTransaction { | |
var bytes: [UInt8] = [0x09, 0x5e, 0xa7, 0xb3] | |
bytes.append(contentsOf: spender.rawAddress.leftPad(with: 0, multipleOf: 32)) | |
bytes.append(contentsOf: value.quantity.makeBytes().leftPad(with: 0, to: 32)) | |
let data = EthereumData(bytes: bytes) | |
let tx = EthereumTransaction(nonce: nonce, gasPrice: gasPrice, gasLimit: gasLimit, to: address, value: 0, data: data, chainId: chainId) | |
return tx | |
} | |
} | |
} | |
fileprivate extension Array where Element == UInt8 { | |
func leftPad(with: UInt8, multipleOf: Int) -> [UInt8] { | |
let paddingSize = multipleOf - (count % multipleOf) | |
let padding = [UInt8].init(repeating: with, count: paddingSize) | |
var newArray = self | |
newArray.insert(contentsOf: padding, at: 0) | |
return newArray | |
} | |
func leftPad(with: UInt8, to: Int) -> [UInt8] { | |
if count >= to { | |
return self | |
} | |
let paddingSize = to - count | |
let padding = [UInt8].init(repeating: with, count: paddingSize) | |
var newArray = self | |
newArray.insert(contentsOf: padding, at: 0) | |
return newArray | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment