< Zpět na články

Jak vytvořit aplikaci pro iOS volání Ethereum Smart Contracts

Ethereum smart contracts mají širokou škálu použití, ale dosud bylo obtížné je volat z aplikace pro iOS. To se nyní změnilo! Prostřednictvím softwaru Ethereum iOS Dev Kit a EtherKit můžete bez problémů začít. Na konci tohoto tutorialu budete moci volat jakoukoli veřejnou funkci Contractu definovanou v ABI (Application Binary Interface).

Začínáme

Pro tento projekt budeme používat Xcode 10.0 a ContractCodegen 0.1. Doporučujeme také používat naši iOS MVVM Project Template, ale abychom tutorial udrželi jednoduchý, použijeme normální strukturu projektu iOS.

Nejdříve vytvoříme nový iOS projekt a nazveme jej například EthereumContracts. Stáhněte si náš example contract abi.json soubor zde. Po dokončení stahování přetáhněte soubor do projektu v Xcode. Ten by měl vypadat takto:

screenshot: Download our example contract abi.json file to your Xcode project

Instalace ContractCodegen

V další části tutoriálu si stáhneme ContractCodegen z našeho Ethereum iOS Dev Kit. Za tímto účelem budu používat Cocoapods, které automaticky stahují potřebné dependencies, ale existují i ​​jiné dostupné metody, které jsou popsané na Ethereum iOS Dev Kit Githubu.
V root directory (kořenovém adresáři) projektu vytvořte Podfile a vložte tento kód:

platform :ios, '10.3'  
project 'EthereumContracts'  
  
inhibit_all_warnings!  
use_frameworks!  
  
target 'EthereumContracts' do  
   pod 'ContractCodegen', '~> x.y.z'  
end  

Otevřete Terminal a vložte tento příkaz:

pod install 

Po dokončení příkazu zavřete náš projekt EthereumContracts a ve Finderu otevřete EthereumContracts.xcworkspace.
Skvělé! Nyní vygenerujeme kód Swift, abychom mohli komunikovat s naším Smart Contractem ?

Generování Swift kódu

Za prvé, ujistěte se, že jste v root directory projektu. Jste-li, můžeme generovat Swift kód jednoduše, pomocí tohoto příkazu:

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

Když se vás příkaz zeptá, který cíl chcete použít, je to poměrně jednoduché – použijte ten jediný možný, tj. možnost číslo jedna ?
A voilá, pokud jste dostali zprávu "Code generation: ✅", vytvořili jste svůj první kód Swift pro Ethereum Smart Contracts ?

Nyní byste měli vidět skupinu vygenerovaných Contractů a dva soubory – SharedContract.swift a HelloContract.swift. První z nich pomáhá s vyvoláním jednotlivých metod, které jsou definovány ve Smart Contractech (v našem případě je to HelloContract) a stejné je to i pro všechny ostatní generované contracty.

A ještě z té zábavné části – pomocí našeho vygenerovaného kódu si zavoláme funkce z našich contractů.

Vytváření klíče

Přejděte na stránku ViewController a v horní části souboru napište:

import EtherKit

Nyní musíme vybrat, kterou síť budeme využívat pro komunikaci se Smart Contracty. Za tímto účelem definujeme proměnnou v ViewController:

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

Můžete použít jakoukoli adresu URL, kterou chcete - ta, kterou vidíte v řetězci, je pouze příklad.
Potom budeme pokračovat v naší funkci viewDidLoad () a vytvoříme si klíče:

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),  
            	]  
    	)

Whoah! Co to všechno je?! Ve skutečnosti je to jednoduché… opravdu :)

Nejprve vytvoříme mnemonic sentence (mnemotechnickou větu) – tato věta se používá k vytvoření soukromých a veřejných klíčů, stejně jako adres. Chcete-li si vytvořit vlastní, což samozřejmě doporučujeme, můžete například použít peněženku MyCrypto, která je ke stažení zde. HDKey.Private.create potom vytvoří náš hlavní node, ze kterého jsou odvozeny všechny ostatní veřejné a soukromé klíče, stejně jako adresy.
Jak můžete vidět, kompilátor nás nyní upozorňuje:

Když se podíváme na funkci HDKey.Private.create, můžeme vidět, že má dokončovací parametr Result ) -> Void. Důvodem je to, že vytvoření našeho účtu je asynchronní operace, a proto budeme muset naše Smart Contracty volat až po dokončení této funkce. Abychom měli náš kód jednoduchý a čitelný, vytvoříme novou funkci, ze které budeme volat náš contract:

private func testContract() {  
  
}

Nyní voláme tuto funkci z dokončení, které jsem uvedl dříve:

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()  
    	}

Buďte trpěliví, blížíme se konečnému výsledku ?

Voláme Contract

Vraťte se na funkci testContract (), kterou jsme vytvořili dříve. Nejprve musíme najít jeden z našich vytvořených klíčů v úložišti pomocí klíčových cest (níže uvedený kód prochází stromem na konkrétní místo):

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),  
        	])

A potom už do konečné části kódu, blížíme se do finále!

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.")  
        	}  
    	}

Podívejme se tedy, jak to funguje.
testContractAddress odkazuje na naši vytvořenou Smart Conracts adresu. Chcete-li používat vlastní, nahraďte řetězec požadovaným hex code (hexadecimálním kódem).

Zbytek kódu je volání samotné funkce Contract. Myslím, že je to samo o sobě dostatečně popisné, ale projdeme si to společně, aby to bylo opravdu jasné.
Najdeme všechny naše funkce HelloContract a deklarujeme, který Smart Contract chceme použít s query.helloContract (at: testContractAddress). Pak si vybereme jednu z funkcí, v tomto příkladu jsem zvolil funkci testString, která má jako vstup řetězec String (tato hodnota bude použita naším Smart Contractem). Poté pošleme tato data přes send. Key value (klíčová hodnota) je ta, kterou jsme našli v našem storage (úložišti) již dříve a amount (částka) říká, kolik Etherea chceme poslat (jak vidíte, používáme typealias pro UInt256 pro lepší čitelnost) send a potom se vrátit na SignalProducer. Pokud nevíte, co to je, můžete si o tom přečíst v dokumentaci ReactiveSwift.
Je-li volání úspěšné, vrátí Hash typ. To je ten samý hash transakce, kterou jsme prve posílali.

Podívejme se, jestli to funguje!

Pokuste se spustit aplikaci a pokud se na výstupu zobrazí hash a řetězec "Test greetings succeeded!", právě jste volali svou první smart contract function pomocí Swift! ?

Ještě jedna věc by měla být řečena. Existují dva typy Smart funkcí – payable a non-payable. O tento rozdíl se postará vygenerovaný Smart Contract kód, takže jediný rozdíl, který uvidíte ve svém kódu mezi těmito dvěma typy, je to, že při volání funkce non-payable bude parametr amount vynechán (protože žádné Ethereum by nemělo být odesláno). Docela jednoduché, že? ?

Chcete-li se podívat na celý projekt, můžete si ho stáhnout zde.

Ještě víc čtení

Pokryli jsme sice spoustu témat, ale pokud máte zájem dozvědět se více do hloubky, jak to všechno funguje, nebo se dál rozvíjet, tady je několik odkazů, které vám pomůžou začít:  

Ethereum iOS Dev Kit – githubová stránka Ethereum iOS Dev Kit (včetně ContractCodegen)

EtherKit – githubová stránka o frameworku používaném pro odesílání transakcí

Infura – služba, kterou používáme pro bezplatnou síť geth

Solidity – Solidity language se používá pro psaní smart contracts, najdete zde také všechny typy vstupů a funkcí

Ledger – dokumentace o tom jak klíče a jejich práve fungují (včetně mnemonic sentence)

Marek Fořt
Marek Fořt
iOS Developer

Máte zájem o spolupráci? Pojďme to probrat osobně!