PocketEth 0.0.3

PocketEth 0.0.3

Pabel Nunez L. 维护。



 
依赖于
Pocket~> 0.0.3
web3swift~> 2.0.4
CryptoSwift>= 0
 

PocketEth 0.0.3

  • Luis C. de Leon 和 Pabel Nunez L.

pocket-ios-eth

是一个符合 PocketPlugin 接口的 Ethereum 插件,适用于 Pocket iOS SDK。使用 web3.swiftCryptoswift 进行核心加密和与 Ethereum 相关的功能。符合 Pocket API 规范。

安装

需要在您的 Podfile 中安装以下 pod

pod 'SwiftKeychainWrapper', :git => '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="">[email protected]:jrendel/SwiftKeychainWrapper.git', :branch => 'develop', :commit => '77f73c354d695d976bcf1437fc9fbcea981aa2b4'

pod 'Pocket', :git => 'https://github.com/pokt-network/pocket-ios-eth.git', :branch => 'master'

准备工作

Pocket Network 为测试提供了一个在 Rinkeby 运行的节点。 https://ethereum.pokt.network

为了轻松设置,请按照以下步骤操作

1- 在您的 appDelegate 中导入 PocketPocketEth 2- 将 Configuration 协议添加到类中:class AppDelegate: UIResponder, UIApplicationDelegate, Configuration, {

3- 使用节点 URL 实现 nodeURLvar nodeURL: URL { get { return URL.init(string: "https://ethereum.pokt.network")! } }

子网络

目前Pocket团队提供 https://ethereum.pokt.network 端点,该端点支持主网和Rinkeby测试网,以下为对应的 subnetwork 标识符

1 代表主网,4 代表Rinkeby

功能

创建钱包

public static func createWallet(subnetwork: String, data: [AnyHashable : Any]?) throws -> Wallet

钱包创建主要使用web3库和 SECP256k1.generatePrivateKey 函数,并将私钥保存到设备上的keystore中。开发者无需担心加密、存储或从设备中检索钱包。

示例如 BANANO Quest

let wallet = try PocketEth.createWallet(subnetwork: subnetwork, data: nil)
if try wallet.save(passphrase: walletPassphrase) == false {
    throw PlayerPersistenceError.walletCreationError
}

导入钱包

public static func importWallet(subnetwork: String, privateKey: String, address: String?, data: [AnyHashable : Any]?) throws -> Wallet

导入钱包时,用户必须传入其明文私钥。

创建交易

public static func createTransaction(wallet: Wallet, params: [AnyHashable : Any]) throws -> Transaction

创建以太坊交易需要以下参数

  • nonce:每次在账户上创建交易时递增的计数器。您可以使用 eth_getTransactionCount 查询获取当前交易计数。
  • gasPrice:以wei计价的交易价格
  • gasLimit:以wei计价的交易最大 gas 数量
  • to:接收交易公共地址
  • value(可选):在交易中发送的 ETH 数量
  • data(可选):例如在智能合约上调用函数的 ABI 数据可以通过数据字段发送

通过将此作为 params 字典传入,以太坊插件抽象了开发者为创建交易所面临的所有困难,并返回一个简单的 Transaction 对象。例如,在 BANANO Quest 中创建任务的事务

定义合约函数ABI

let functionABI = "{\"constant\":false,\"inputs\":[{\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"name\":\"_name\",\"type\":\"string\"},{\"name\":\"_hint\",\"type\":\"string\"},{\"name\":\"_maxWinners\",\"type\":\"uint256\"},{\"name\":\"_merkleRoot\",\"type\":\"bytes32\"},{\"name\":\"_merkleBody\",\"type\":\"string\"},{\"name\":\"_metadata\",\"type\":\"string\"}],\"name\":\"createQuest\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"}"

定义参数

var functionParameters = [AnyObject]()
functionParameters.append(tokenAddress as AnyObject)
functionParameters.append(questName.description as AnyObject)
functionParameters.append(hint.description as AnyObject)
functionParameters.append(maxWinners as AnyObject)
functionParameters.append(merkleRoot as AnyObject)
functionParameters.append(merkleBody as AnyObject)
functionParameters.append(metadata as AnyObject)

let txParams = [
    "from": wallet.address,
    "nonce": BigUInt.init(transactionCount),
    "to": tavernAddress,
    "value": BigUInt.init(ethPrizeWei),
    "chainID": AppConfiguration.chainID,
    "gasLimit": BigUInt.init(2000000),
    "gasPrice": BigUInt.init(1000000000),
    "data": [
        "abi": functionABI,
        "params": functionParameters
    ] as [AnyHashable: Any]
] as [AnyHashable: Any]

创建交易

guard let transaction = try? PocketEth.createTransaction(wallet: wallet, params: txParams) else {
self.error = PocketPluginError.transactionCreationError("Error creating transaction")
self.finish()
return
}

发送交易

Pocket.shared.sendTransaction(transaction: transaction) { (transactionResponse, error) in
if error != nil {
self.error = error
self.finish()
return
}

解析交易哈希响应

guard let txHash = transactionResponse?.hash else {
self.error = UploadQuestOperationError.invalidTxHash
self.finish()
return
}

self.txHash = txHash
self.finish()

创建查询

public static func createQuery(subnetwork: String, params: [AnyHashable: Any], decoder: [AnyHashable: Any]?) throws -> Query

要为以太坊创建一个Pocket查询,你需要为你要进行的特定JSON RPC调用提供subnetworkparams。为了创建一个查询,有两种类型的参数:

  • rpcMethod:你要调用的智能合约方法的名称
  • rpcParams:你要调用的智能合约方法的输入

decoder字典允许开发者指定读取请求的返回类型。

以下是一个示例,展示如何创建一个getBalance查询并使用Pocket获取账户的余额。

let params = [
"rpcMethod": "eth_getBalance",
"rpcParams": [address, "latest"]
] as [AnyHashable: Any]

guard let query = try? PocketEth.createQuery(params: params, decoder: nil) else {
self.error = PocketPluginError.queryCreationError("Error creating query")
self.finish()
return
}

Pocket.shared.executeQuery(query: query) { (queryResponse, error) in
if error != nil {
self.error = error
self.finish()
return
}

为智能合约中的常量创建查询略为复杂,因为你需要提供你调用方法的ABI接口、functionParametersdecoder。以下是从BANANO Quest获取任务列表的一个示例。

创建交易

var tx = [AnyHashable: Any]()

创建ABI

let functionABI = "{\"constant\":true,\"inputs\":[{\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"name\":\"_questIndex\",\"type\":\"uint256\"}],\"name\":\"getQuest\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"},{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"bytes32\"},{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"bool\"},{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}"

传入地址和索引

let functionParameters = [tokenAddress, questIndex] as [AnyObject]

编码ABI和参数

guard let data = try? PocketEth.encodeFunction(functionABI: functionABI, parameters: functionParameters).toHexString() else {
self.error = PocketPluginError.queryCreationError("Error creating query")
self.finish()
return
}

为以太坊交易添加参数

tx["to"] = tavernAddress
tx["data"] = "0x" + data
tx["from"] = self.playerAddress

创建最终以太坊查询的参数

let params = [
"rpcMethod": "eth_call",
"rpcParams": [tx, "latest"]
] as [AnyHashable: Any]

创建解码器

let decoder = [
"returnTypes": ["address", "uint256", "string", "string", "bytes32", "string", "uint256", "string", "bool", "uint256", "uint256"]
] as [AnyHashable : Any]

创建查询对象

guard let query = try? PocketEth.createQuery(params: params, decoder: decoder) else {
self.error = PocketPluginError.queryCreationError("Error creating query")
self.finish()
return
}

执行查询

Pocket.shared.executeQuery(query: query) { (queryResponse, error) in
if error != nil {
self.error = error
self.finish()
return
}

获取并解析响应

guard let questArr = queryResponse?.result?.value() as? [JSON] else {
    self.error = DownloadQuestOperationError.questParsing
    self.finish()
    return
}

    let creator = questArr[0].value() as? String ?? ""
    let index = questArr[1].value() as? String ?? "0"
    let name = questArr[2].value() as? String ?? ""
    let hint = questArr[3].value() as? String ?? ""
    let merkleRoot = questArr[4].value() as? String ?? ""
    let merkleBody = questArr[5].value() as? String ?? ""
    let maxWinners = questArr[6].value() as? String ?? "0"
    let metadata = questArr[7].value() as? String ?? ""
    let valid = questArr[8].value() as? Bool ?? false
    let winnersAmount = questArr[9].value() as? String ?? "0"
    let claimersAmount = questArr[10].value() as? String ?? "0"

self.questDict = [
    "creator": creator,
    "index": index,
    "name": name,
    "hint": hint,
    "merkleRoot": merkleRoot,
    "merkleBody": merkleBody,
    "maxWinners": maxWinners,
    "metadata": metadata,
    "valid": valid,
    "winnersAmount": winnersAmount,
    "claimersAmount": claimersAmount
] as [AnyHashable: Any]
    self.finish()