Swift编写的EOS区块链开源框架SwiftyEOS

SwiftyEOS是一个用于与EOS交互的开源框架,用Swift编写。可以在iOS和macOS上使用。

特点:

  • EOS密钥对生成
  • 私钥导入
  • 签名哈希
  • 基本的RPC API(链/历史)可查询客户端
  • 交易(EOS token 转账)
  • 帮助类处理iOS上的脱机钱包
  • 在iOS上加密/解密导入私钥

如何使用它

  • 1.将LibrariesSources文件夹复制到项目中,不需要main.swift
  • 2.如果不是针对iOS平台,请删除Sources/Utils/iOS
  • 3.将Libraries/include添加到Header搜索路径中。
  • 4.将Libraries/include/Bridging-Header.h设置为Objective-C Bridging Header。如果你有自己的bridging header,请复制该文件中的所有导入内容并粘贴到你自己的文件中。
  • 5.编译然后等结果

密钥对生成

SwiftyEOS现在支持secp256k1密钥对。

secp256r1密钥对生成有bug但我无法弄清楚原因。从cleos创建的单元测试创建密钥--r1不会通过。你可能不会将secp256r1视为一个选项,因为cleos wallet命令也无法导入这些键。

生成随机密钥对:

let (pk, pub) = generateRandomKeyPair(enclave: .Secp256k1)

很容易对吧?

print("private key: \(pk!.wif())")
print("public key : \(pub!.wif())")

// private key: PVT_K1_5HxrYTdZX89zodtJhTzCk87MfNZAkiBRfFvSX8kacYjtwaDpTkL
// public key : PUB_K1_4yDYdmcVcXxAxeNsUWRG7x9FKQE4HbJZdzgZFv1AYxk6oSVcLd

PVT_K1_PUB_K1_前缀是标准密钥表示的一部分。但是EOS系统和SwiftyEOS也支持旧方式:

print("private key: \(pk!.rawPrivateKey())")
print("public key : \(pub!.rawPublicKey())")

// private key: 5HxrYTdZX89zodtJhTzCk87MfNZAkiBRfFvSX8kacYjtwaDpTkL
// public key : EOS4yDYdmcVcXxAxeNsUWRG7x9FKQE4HbJZdzgZFv1AYxk6oSVcLd

导入现有密钥:

let importedPk = try PrivateKey(keyString: "5HxrYTdZX89zodtJhTzCk87MfNZAkiBRfFvSX8kacYjtwaDpTkL")
let importedPub = PublicKey(privateKey: importedPk!)

带分隔符和前缀:

let importedPk = try PrivateKey(keyString: "PVT_K1_5HxrYTdZX89zodtJhTzCk87MfNZAkiBRfFvSX8kacYjtwaDpTkL")
let importedPub = PublicKey(privateKey: importedPk!)

RPC API

EOSRPC.sharedInstance.chainInfo { (chainInfo, error) in
    if error == nil {
        print("Success: \(chainInfo!)")
    } else {
        print("Error: \(error!.localizedDescription)")
    }
}

目前我们有一些基本的RPC端点,你可以在Sources/SwiftyEOS/Network找到它。

iOS的密钥存储

我们有SEWallet.swift iOS版离线钱包管理助手。

SEWallet.swift可以方便地保存AES加密的密钥信息到文件系统。默认位置是应用程序的沙盒。

目前还不支持多个钱包管理。

在iOS上创建新钱包

在Objective-C中:

[SEKeystoreService.sharedInstance newAccountWithPasscode:passcode succeed:^(SELocalAccount *account) {
} failed:^(NSError *error) {
        
}];

检索已保存的钱包

[SELocalAccount currentAccount];

如果没有保存钱包,它将返回零。

交易

交易行为目前尚未完全支持,但你仍可以尝试使用main.swift中的示例代码。

整个功能完成后,将提供相关文件。

  • 货币转账(2018.08.15)
  • 提交一般交易(2018.08.16)
  • iOS上的设备上(离线)钱包锁定和解锁(2018.08.17)
  • 押注/取消押注/净值(2018.08.28)
  • 买/卖ram(2018.08.28)
  • 创建账户(2018.10)
  • 用params列表推送交易(2018.11.05)
  • 使用助记符创建/导入密钥对

货币转账

var transfer = Transfer()
transfer.from = "agoodaccount"
transfer.to = "gq3dinztgage"
transfer.quantity = "1.0000 EOS"
transfer.memo = "eureka"

Currency.transferCurrency(transfer: transfer, code: "eosio.token", privateKey: importedPk!, completion: { (result, error) in
    if error != nil {
        if error is RPCErrorResponse {
            print("\((error as! RPCErrorResponse).errorDescription())")
        } else {
            print("other error: \(String(describing: error?.localizedDescription))")
        }
    } else {
        print("done.")
    }
})

提交一般交易

swift:

let account = "raoji"
let asset = "1.0000 EPRA"

let data = "{\"hey\": {\"account\":\"" + account  + "\", \"quantity\":\"" + asset + "\"}}"
let abi = try! AbiJson(code: "prabox1", action: "withdraw", json: data)

TransactionUtil.pushTransaction(abi: abi, account: account, privateKey: importedPk!, completion: { (result, error) in
    if error != nil {
        if (error! as NSError).code == RPCErrorResponse.ErrorCode {
            print("\(((error! as NSError).userInfo[RPCErrorResponse.ErrorKey] as! RPCErrorResponse).errorDescription())")
        } else {
            print("other error: \(String(describing: error?.localizedDescription))")
        }
    } else {
        print("Ok. Txid: \(result!.transactionId)")
    }
})

Objective-C:

AbiJson *your_abi;
[TransactionUtil pushTransactionWithAbi:your_abi
                                account:@"your_account"
                               pkString:@"your_private_key"
                             completion:^(TransactionResult *result, NSError *error) {
        
}];

iOS上的设备上(离线)钱包锁定和解锁

我们添加locktimedUnlock函数到SELocalAccount

Cpu/net/ram 操作

ResourceUtil.swift文件包括ResourceUtil类,包括下面几个方法:

  • stakeResource
  • unstakeResource
  • buyRam
  • sellRam

Stake resource:

ResourceUtil.stakeResource(account: "raoji", net: 1.0, cpu: 1.0, pkString: "5HsaHvRCPrjU3yhapB5rLRyuKHuFTsziidA13Uw6WnQTeJAG3t4", completion: { (result, error) in
})

助记符

建一个新的密钥对:

let (pk, pub, mn) = generateRandomKeyPair(enclave: .Secp256k1)

导入现有助记符:

let (pk, mn) = PrivateKey(enclave: .Secp256k1, mnemonicString: "your words here")

我们在SEWallet.swift中有密钥管理的iOS助手API和助记符。现在可以使用SEKeystoreService类创建和导入助记符(如果你自己存储,则可以使用SEKeystore更深入的API):

SEKeystoreService.sharedInstance.newAccountAndMnemonic(passcode: "your pass here", succeed: { (account, mnemonic) in

}) { (error) in

}

我们正在为所有顶级API使用NSObject固有类,因此在不提供额外桥接文件的情况下调用Objective-C也是一样的。

SEWallet.swift文件中也有iOS的帮助方法。

谢谢。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏华仔的技术笔记

Ubuntu系统搭建以太坊框架总结

21140
来自专栏移动端周边技术扩展

防抓包(证书攻击)策略-iOS

2.1把证书机构签完的公钥证书放到工程里名称为"server.cer" 2.2设置AFSSLPinningMode

50030
来自专栏移动端周边技术扩展

python收发邮件客户端

28730
来自专栏JavaEE

spring整合kaptcha验证码kaptcha简介:开发工具及使用的核心技术:正式开始:

521130
来自专栏农夫安全

【干货】骚姿势破解后台管理员密码

骚姿势破解后台管理员密码 0x01 前言 该文为admin原创文章 当你某个时候通过注入得到了admin的密码,然后把他放到md5解密的时候,激动不已的等待着结...

50160
来自专栏张绍文的专栏

基于 TLS 1.3的微信安全通信协议 mmtls 介绍(下)

随着近些年网络安全事情的频繁发生,使得用户对网络通信安全的意识越来越强。国内外的网络服务提供商都逐渐提供全站的安全通信服务,如国内的淘宝、百度先后宣布已经完成了...

2.1K10
来自专栏小白安全

小白博客 Linux下暴力破解工具Hydra详解

Number one of the biggest security holes are passwords, as every password secu...

79170
来自专栏FreeBuf

一个纯JS脚本的文档敲诈者剖析(附解密工具)

0x00 概述 近日,腾讯反病毒实验室拦截到一个名为RAA的敲诈者木马,其所有的功能均在JS脚本里完成。这有别于过往敲诈者仅把JS脚本当作一个下载器,去下载和执...

55270
来自专栏owent

接入letsencrypt+全面启用HTTP/2

之前我的域名只有owent.net和www.owent.net买了SSL证书,现在有letsencrypt可以拿到免费的SSL签证,就稍微花了点时间把我的域名的...

10820
来自专栏LhWorld哥陪你聊算法

【Azkaban搭建】---Azkaban 3.25.0搭建细则 超实用

Azkaban是一个工作流调度工具,因为需要各个任务之间有依赖关系,传统的Crontab 任务已经不能满足。

17550

扫码关注云+社区

领取腾讯云代金券