iOS應用程序如何調用以太坊智能合約 原

以太坊智能合約有各種各樣的用例,但到目前爲止,從你的iOS應用程序中調用它們非常困難。不過如果使用以太坊iOS開發套件EtherKit,這種情況會改善很多,你可以立即開始使用。在本教程結束時,你將能夠調用其ABI(應用程序二進制接口)中定義的任何公共合約函數。

對於這個項目,我們將使用Xcode 10.0和ContractCodegen 0.1。我們還建議使用iOS MVVM項目模板,但爲了使本教程簡單,我們將使用正常的iOS項目結構。

首先,我們將創建一個新的iOS項目,並將其稱爲EthereumContracts。在這裏下載我們的示例合約abi.json文件。下載成功後,將文件拖到Xcode項目中。你的Xcode項目現在應該如下所示:

安裝ContractCodegen

在本教程的下一部分中,我們將從我們的以太坊iOS開發工具包下載ContractCodegen。爲此,我將使用Cocoapods,它將自動下載必要的依賴項,但還有其他方法可用,在以太坊iOS開發套件Github中有描述。

在項目根目錄中創建Podfile並插入以下代碼:

platform :ios, '10.3'
project 'EthereumContracts'

inhibit_all_warnings!
use_frameworks!

target 'EthereumContracts' do
   pod 'ContractCodegen', '~> x.y.z'
end

打開終端並粘貼此命令:

pod install 

當此命令完成時,關閉我們的EthereumContracts項目並在Finder中打開EthereumContracts.xcworkspace

很好!現在讓我們生成Swift代碼以與我們的智能合約進行交互。

生成Swift代碼

首先,確保你在項目根目錄中。如果你已經在了,我們可以非常簡單地生成我們的Swift代碼,只需使用以下命令:

Pods/ContractCodegen/ContractCodegen/bin/contractgen HelloContract EthereumContracts/abi.json -x EthereumContracts.xcodeproj -o EthereumContracts/GeneraredContracts

當命令詢問你使用哪個選項時,非常簡單,只使用一個,即第一個選項。

瞧,如果你收到“Code generation: ok”的消息,你已經爲以太坊智能合約創建了第一個Swift代碼。

你現在應該看到一組Generated Contracts和其中的兩個文件:SharedContract.swiftHelloContract.swift。第一個幫助我們調用合約文件中定義的各個方法(在我們的例子中是HelloContract),並且對於所有生成的合約都是相同的。

有趣的那部分實際上是使用我們生成的代碼來調用我們自己的合約。

創建密鑰

導航到我們的ViewController並在文件頂部寫:

import EtherKit

現在我們需要聲明我們將使用哪個geth網絡與智能合約進行通信。爲了做到這一點,讓我們在ViewController中定義一個屬性:

let query = EtherQuery(URL(string: "https://rinkeby.infura.io/v3/9f1a1e0782ab40c8b39fe189615714d0")!, connectionMode: .http)

你可以使用任何所需的URL,你在字符串中看到的只是我們爲你提供的URL。

然後我們將繼續在viewDidLoad()函數中創建我們的密鑰:

let walletStorage = KeychainStorageStrategy(identifier: "cz.ackee.etherkit.example")

HDKey.Private.create(
        	with: MnemonicStorageStrategy(walletStorage),
        	mnemonic: sentence,
        	network: .main,
        	path: [
            	KeyPathNode(at: 44, hardened: true),
            	KeyPathNode(at: 60, hardened: true),
            	KeyPathNode(at: 0, hardened: true),
            	KeyPathNode(at: 0),
            	]
    	)

這很簡單,對吧。

首先,我們創建助記句,這句話用於創建私鑰和公鑰以及地址。要創建你自己的,這是很顯然的,你可以使用從此處下載的MyCrypto錢包示例。然後,HDKey.Private.create創建我們的主節點,從該節點派生所有其他公鑰和私鑰以及地址。

如你所見,編譯器現在向我們顯示此警告:

當我們查看HDKey.Private.create的函數時,我們可以看到它有一個完成參數Result<HDKey.Private, EtherKitError>) -> Void。這是因爲創建我們的帳戶是異步操作,因此我們需要在此功能完成後開始調用我們的智能合約。

爲了使我們的代碼簡單易讀,我們將創建一個新函數,我們將從中調用我們的合約:

private func testContract() {

}

現在我們從前面提到的完成中調用這個函數,如下所示:

HDKey.Private.create(
        	with: MnemonicStorageStrategy(walletStorage),
        	mnemonic: sentence,
        	network: .main,
        	path: [
            	KeyPathNode(at: 44, hardened: true),
            	KeyPathNode(at: 60, hardened: true),
            	KeyPathNode(at: 0, hardened: true),
            	KeyPathNode(at: 0),
            	]
    	) { [weak self] _ in
        	self?.testContract()
    	}

請耐心等待,我們越來越接近最終結果。

調用我們的合約

前往我們之前創建的testContract()函數。首先,我們需要使用關鍵路徑找到存儲在存儲中的一個創建的密鑰(下面的代碼只是通過樹到達特定位置):

let walletStorage = KeychainStorageStrategy(identifier: "cz.ackee.etherkit.example")
let key = HDKey.Private(walletStorage, network: .rinkeby, path: [
        	KeyPathNode(at: 44, hardened: true),
        	KeyPathNode(at: 60, hardened: true),
        	KeyPathNode(at: 0, hardened: true),
        	KeyPathNode(at: 1),
        	])

到代碼的最後部分,我們差不多了!

let testContractAddress = try! Address(describing: "0xb8f016F3529b198b4a06574f3E9BDc04948ad852")
    	query.helloContract(at: testContractAddress).testString(greetString: "Greetings!").send(using: key, amount: Wei(10)).startWithResult { result in
        	switch result {
        	case .success(let hash):
            	print(hash)
            	print("Test greetings succeeded!")
        	case .failure(let error):
            	print(error)
            	print("Test greetings failed.")
        	}
    	}

好的,讓我們看看這是做什麼的。

testContractAddress指向我們創建的智能合約地址。要使用你自己的字符串替換它,請使用所需的十六進制代碼。

其餘的代碼就是調用本身。我認爲這是非常自我描述的,但我們將運行它,只是爲了清楚。

我們找到所有的HelloContract函數,並聲明我們要使用query.helloContract(at:testContractAddress)的合約地址。然後我們選擇其中一個函數,在這個例子中我選擇了函數testString,它將String作爲輸入(這個值將由我們的智能合約使用)。之後,我們通過send發送此數據。密鑰值是我們之前在存儲中找到的密鑰值,amount聲明瞭我們想要發送多少以太坊(正如你所看到的,我們爲UInt256使用了typealias以獲得更好的可讀性)。然後send返回SignalProducer。如果你不知道那是什麼意思,請在ReactiveSwift文檔中閱讀更多相關信息。

如果調用成功,則返回Hash類型。這只是我們發送的交易的哈希值。

讓我們看看它是否有效!

嘗試運行應用程序,如果你在輸出中看到一個哈希和一個字符串“Test greetings succeeded!”,你剛剛使用Swift調用了你的第一個智能合約函數!

還有一件事應該說。智能功能有兩種類型:應付款和非應付款。這種差異由生成的智能合約代碼處理,因此你在代碼中將在這兩種類型之間看到的唯一區別是,當調用非應付函數時,將省略參數金額(因爲不應發送以太坊)。很簡單,是吧?

如果想查看整個項目,可以在此處下載

=====================================================================

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章