2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

web3swift を使って iOS アプリから Ethereum につないでみるテスト

Last updated at Posted at 2020-03-04

iOS アプリからイーサリアムにつないでテストするまでの簡単な手順をまとめてみました。
イーサリアムクライアントとして、web3swift(matter-labs) を利用しています。

「ややこしい話は抜きだ!」という方は、GitHub に手順後のプロジェクトが置いてあるのでお使いくださいませ。

では、ちゃっちゃといきましょう。

プロジェクトの作成

Xcode を起動して Create a new Xcode project から新規プロジェクトを作成します。
ss000.png

このアプリは画面タップでテストを実行させたいので、タップ処理のひな型のある Game を選択。
ss001.png

プロダクト名は StudyWeb3Swift、チームと組織名&IDはご自身の開発者登録内容にて設定してください。
ss002.png

プロジェクトフォルダの出力先をお好みで設定して Create
ss003.png

空のプロジェクトのできあがりです。
ss004.png

web3swift の導入

ライブラリの導入は CocoaPods にて行います。
CocoaPods はプロジェクトフォルダ内にファイルを出力するので、Xcode を終了して StudyWeb3Swift プロジェクトを閉じておきます。

まず、StudyWeb3Swift プロジェクトフォルダの直下(StudyWeb3Swift.xcodeproj と同じ階層)に、インストールするライブラリを指定する Podfile を、下記の内容で作成します(※ここでは、iOS のバージョンを 9.0 にしていますが、この値はプロジェクトのデプロイ先のバージョン指定とともに、ご自身の環境に応じて調整してください)。

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0'

target 'StudyWeb3Swift' do
    use_frameworks!
    pod 'web3swift'
end

ss006.png

ターミナルを開いて、下記コマンドにて CocoaPods をインストールします(※すでに、CocoaPods をインストール済みの方は、この手順はスキップできます)。

$ sudo gem install cocoapods

ss008_2.png

つづいて、ターミナル上で、StudyWeb3Swift プロジェクトフォルダへ移動し、下記コマンドにて、Podfile で指定した web3swift ライブラリをインストールします。

ss011_2.png

インストールが正常に終了すると、StudyWeb3Swift フォルダ直下に、Podfile.lockPods/StudyWeb3Swift.xcworkspace が生成されます。

ss012.png

生成された StudyWeb3Swift.xcworkspaceStudyWeb3Swift.xcodeprojPods/ 内のライブラリを協調させてくれる環境となり、以降の作業は、このワークスペース上で行うことになります。

では、StudyWeb3Swift.xcworkspaceXcode で開いて、Pods 内の様子を確認し、web3swift が導入されていることをチェックしましょう(※間違えて StudyWeb3Swift.xcodeproj を開いてしまわないようご注意ください)。

ss014.png

テストコードの組み込み

下記の3ファイルをソースフォルダ StudyWeb3Swift/StudyWeb3Swift にコピーします。

ContractHelloWorld.swift
TestWeb3.swift
Web3Helper.swift

ss015.png

つづいて、コピーしたソースコードを、StudyWeb3Swift プロジェクトにインポートします。StudyWeb3SwiftStudyWeb3Swift を右クリックして Add Files to"StudyWeb3Swift"... を選択し...

ss016.png

先ほどコピーした3つのファイルを選択して Add します。

ss017.png

Xcode 上で追加したソースが認識されていたらインポートは完了です。
ss018.png

追加されたソースコードの役割は下記となります。
 ・ContractHelloWorld … イーサリアムにデプロイされたコントラクトをラップするクラス
 ・TestWeb3 … テスト処理を担当するクラス
 ・Web3Helper … イーサリアムアカウントを管理するヘルパークラス

では早速、アプリのタップ処理にテストコードを紐づけましょう。

StudyWeb3SwiftStudyWeb3SwiftGameScene.swift を開き、GameScene クラスのメンバーに、TestWeb3 クラスのインスタンスを追加します。

  private let testWeb3 = TestWeb3()

ss019.png

つづいて、画面がタップされた際に、TestWeb3 のインスタンスがテストを実行するように、func touchDown(atPoint pos : CGPoint) ブロック内に、下記のコードを追加します。

  testWeb3.test()

ss020.png

これで、コーディングは終了です。
あとは、ワークスペースをビルドして実行するだけですが、その前に、iOS の対応バージョンを確認しておきましょう。このテストでは iOS 9.0 を選択していますが、この値はご自身のテスト環境に応じて調整してください。

ss021.png

また、実機で動作させる際は、署名関連の設定もご自身の環境に応じて調整してください。

ss023.png

さていよいよテストです。

iOS端末をPCと接続してスキームの実行対象に設定したら、ProductRun(command+R) でビルド&実行します。

ss022.png

動作確認

アプリが起動したら Xcode 上でログビューを表示し、iOS端末の画面をタップしてテストを開始しましょう。

**一回目のログ(タップで開閉します)**


@--------------------------
@ TestWeb3: start...
@--------------------------
@------------------
@ setTarget
@------------------
@ target: rinkeby
@------------------
@ setKeystore
@------------------
@ CREATE NEW KEYSTORE
@ Write down below json code to import generated account into your wallet apps(e.g. MetaMask)
{"version":3,"id":"2359f351-edce-4f48-9741-45dae1f36917","crypto":{"ciphertext":"0ec98990843f81524362a77a5f0df1fad42373d2209b8c5c20b5290b94afee99","cipherparams":{"iv":"9fa217c4b40c255cd9fe2c8cfae82392"},"kdf":"scrypt","kdfparams":{"r":6,"p":1,"n":4096,"dklen":32,"salt":"e6c1aad4d16d0e9c48bb4dc2445216bed6895fe0d5e5db752b62cc2f2c39bd1a"},"mac":"6455f877dd71d9378d1ad7068be65603fbc9a5daab47db2d2e799f9249675584","cipher":"aes-128-ctr"},"address":"0x87ba44ed65039cba432ae3e8b701b5c17b421245"}
@ privateKey: f992d3e4f3925ddaba0f7130ff7e418d1d0a2bae4cf4f5d196284f8f19c40029
@ saveKeystoreJson: result= true
@ CURRENT KEYSTORE
@ ethereumAddress: 0x87bA44Ed65039cBA432ae3e8b701B5C17b421245
@------------------
@ checkBalance
@------------------
@ balance: 0 wei
@------------------
@ checkSend
@------------------
@ try writeTx.sendPromise().wait()
@ TestWeb3: error: nodeError(desc: "insufficient funds for gas * price + value")
@--------------------------
@ TestWeb3: finished
@--------------------------

テストが開始されると、アプリは Rinkeby テストネットへ接続します。

その後、アプリの Documents 領域にアカウント情報(jsonファイル)があるかをチェックし、有効なファイルが無い場合(初回起動時)、アカウントを新規作成します。この時、作成されたアカウント情報は、key.json の名前でアプリの Documents 領域に保存され、次回以降のテストに利用されます。

ログを見ると、新規アカウント 0x87bA44Ed65039cBA432ae3e8b701B5C17b421245 が作成されていることがわかります。

また、作成直後のアカウントには残高がないので、送金テストが残高不足のエラー "insufficient funds for gas * price + value" により、失敗している様子がうかがえます。

ss024.png

お次は、上記のアカウントへイーサを送金した状況で再テストしてみましょう(※イーサの送金はMetaMask 等で行ってください)。

**二回目のログ(タップで開閉します)**


@--------------------------
@ TestWeb3: start...
@--------------------------
@------------------
@ setTarget
@------------------
@ target: rinkeby
@------------------
@ setKeystore
@------------------
@ loadKeystoreJson: json= {"version":3,"id":"2359f351-edce-4f48-9741-45dae1f36917","crypto":{"ciphertext":"0ec98990843f81524362a77a5f0df1fad42373d2209b8c5c20b5290b94afee99","cipherparams":{"iv":"9fa217c4b40c255cd9fe2c8cfae82392"},"kdf":"scrypt","kdfparams":{"r":6,"p":1,"n":4096,"dklen":32,"salt":"e6c1aad4d16d0e9c48bb4dc2445216bed6895fe0d5e5db752b62cc2f2c39bd1a"},"mac":"6455f877dd71d9378d1ad7068be65603fbc9a5daab47db2d2e799f9249675584","cipher":"aes-128-ctr"},"address":"0x87ba44ed65039cba432ae3e8b701b5c17b421245"}
@ loadKeystore: result= true
@ CURRENT KEYSTORE
@ ethereumAddress: 0x87bA44Ed65039cBA432ae3e8b701B5C17b421245
@------------------
@ checkBalance
@------------------
@ balance: 200000000000000000 wei
@------------------
@ checkSend
@------------------
@ try writeTx.sendPromise().wait()
@ result: TransactionSendingResult(transaction: Transaction
Nonce: 0
Gas price: 1000000000
Gas limit: 21000
To: 0xebfCB28c530a9aAD2e5819d873EB5Cc7b215d1E1
Value: 10000000000000000
Data: 0x
v: 44
r: 87422810951677431415523287396190154043506098492265568492767307684265100910143
s: 5842696374747228610494556784274260904960349939000190988355515076602550996278
Intrinsic chainID: Optional(4)
Infered chainID: Optional(4)
sender: Optional("0x87bA44Ed65039cBA432ae3e8b701B5C17b421245")
hash: Optional("0x49058ce4761b248f10cfbbd3dd7b8c18b35ed7538ebfe5d43d0de2331d75a615")
, hash: "0x49058ce4761b248f10cfbbd3dd7b8c18b35ed7538ebfe5d43d0de2331d75a615")
@------------------
@ checkHelloWorld
@------------------
@ [HelloWorld].getWord: Greeting from web3swift at Mar 2, 2020 22:47:59
@ [HelloWorld].sendWord: Greeting from web3swift at Mar 4, 2020 13:31:02
@ tx: TransactionSendingResult(transaction: Transaction
Nonce: 1
Gas price: 1000000000
Gas limit: 34900
To: 0xd21CE6F369F8281B7D39B47372c8F4A8A77841fc
Value: 0
Data: 0xcd048de60000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002f4772656574696e672066726f6d20776562337377696674206174204d617220342c20323032302031333a33313a30320000000000000000000000000000000000
v: 43
r: 45934615592327133422040104710195506263029144129299763619641629997681409834635
s: 14105001248363733140301949226320798518699267713878394389330067776277426590357
Intrinsic chainID: Optional(4)
Infered chainID: Optional(4)
sender: Optional("0x87bA44Ed65039cBA432ae3e8b701B5C17b421245")
hash: Optional("0x4517fc343aaf4636d64e1660e89103bd4f542c488aa93c392bc630eba35481f1")
, hash: "0x4517fc343aaf4636d64e1660e89103bd4f542c488aa93c392bc630eba35481f1")
@--------------------------
@ TestWeb3: finished
@--------------------------

今回は残高が十分(0.2 eth)あるので、イーサの送金コントラクトへの書き込みテストが成功しているのがわかります。

ss025.png

補足

実装環境

 ・macOS Mojave 10.14.4
 ・Xcode 11.3.1(11C504)

確認端末

 ・iPhoneX iOS 11.2
 ・iPhone7plus iOS 13.3.1
 ・iPhone6plus iOS 10.3.3
 ・iPhone6 iOS 11.2.6
 ・iPhone5s iOS 10.2
 ・iPad(第六世代) iOS 12.2

以上です。
この記事が少しでも、誰かのお役に立ってくれたら嬉しいです。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?