web3SwiftでEthereum開発

# 最初に
今回展開するプログラムは100%セキュリティを担保しているものではありません。
そちらをご理解いただけるようお願いいたします。
##今回この記事を投稿する上で参考にさせていただいたサイト
https://qiita.com/chocovayashi/items/dca4da1ec03f706e2105
https://github.com/matter-labs/web3swift
# 開発環境
Xcode10.2
swift5
# 実装前にやること
外部ライブラリーを導入します。
毎度お馴染みのCocoaPodsさんでpodFileに書き込みます。

```ruby:Podfile
pod 'web3.swift.pod', '~> 2.2.0'
```

# 実装
######Walletアカウント作成

```swift:NewAccont.swift
//ファイル名生成     
let generationFileName = "WalletAccount"
// keystore ファイルを保存するディレクトリのパスを取得
let userDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
var keystoreManager = KeystoreManager.managerForPath(userDir + "/keystore", scanForHDwallets: true)
        
// パスワードを使用する
let password = "1234567890"!
//KeyStoreの生成ファイルを作成
let keystore = try! EthereumKeystoreV3(password: password)!
//生成ファイルをエンコード
let keyData = try! JSONEncoder().encode(keystore.keystoreParams)
//アドレス取得
let address = keystore.addresses!.first!.address
//ファイル書き込み処理
FileManager.default.createFile(atPath: userDir + "/keystore"+"/\(generationFileName).json", contents: keyData, attributes: nil)
        keystoreManager = KeystoreManager.managerForPath(userDir + "/keystore", scanForHDwallets: true)
print("アカウント：\(address)")
```

######イーサリアムの残高取得

```swift:getBalance.swift
//ファイルパス参照
if let dir = FileManager.default.urls( for: .documentDirectory, in: .userDomainMask ).first {
let path_file_name = dir.appendingPathComponent( "keystore/WalletAccount.json" )
            
            do {
                let keystore = try String( contentsOf: path_file_name, encoding: String.Encoding.utf8 )
                //キーストアの設定
                let data = keystore
                let keystoreManager: KeystoreManager
                
                let keystoreSetting = EthereumKeystoreV3(data)!
                keystoreManager = KeystoreManager([keystoreSetting])
                //本番サーバに接続
                let web3 = Web3.InfuraMainnetWeb3()
                web3.addKeystoreManager(keystoreManager)
                
                //残高取得処理
                let walletAddress = EthereumAddress(address)! // Address which balance we want to know
                do{
                    let balanceResult = try web3.eth.getBalance(address: walletAddress)
                    let balanceString = Web3.Utils.formatToEthereumUnits(balanceResult, toUnits: .eth, decimals: 5)!
                    print("残高：\(balanceString)")
                }
                catch{
                    print("エラー：\(error)")
                }
                
            } catch {
                //エラー処理
                print("ファイルない")
            }
        }
```
######Eth送信

```swift:EthSend.swift
//ローカルからFileを検索し取得
        let file_name = "keystore/WalletAccount.json"
        
        if let dir = FileManager.default.urls( for: .documentDirectory, in: .userDomainMask ).first {
            
            let path_file_name = dir.appendingPathComponent( file_name )
            
            do {
                let keystore = try String( contentsOf: path_file_name, encoding: String.Encoding.utf8 )
                print("データ表示:\(keystore)")
                //キーストアの設定
                let data = keystore
                let keystoreManager: KeystoreManager
                
                let keystoreSetting = EthereumKeystoreV3(data)!
                keystoreManager = KeystoreManager([keystoreSetting])
                //本番サーバに接続
                let web3 = Web3.InfuraMainnetWeb3()
                web3.addKeystoreManager(keystoreManager)
                
                //残高取得処理
                let walletAddress = EthereumAddress("自分のアドレス")! // Address which balance we want to know
                do{
                    let balanceResult = try web3.eth.getBalance(address: walletAddress)
                    let balanceString = Web3.Utils.formatToEthereumUnits(balanceResult, toUnits: .eth, decimals: 3)!
                }
                catch{
                    print("エラー：\(error)")
                }
              
                
                //ここからEth送信処理
                let value: String = "0.00001" // In Ether
                let toAddress = EthereumAddress("相手のアドレス")!
                let contract = web3.contract(Web3.Utils.coldWalletABI, at: toAddress, abiVersion: 2)!
                let amount = Web3.Utils.parseToBigUInt(value, units: .eth)
                var options = TransactionOptions.defaultOptions
                options.value = amount
                //送り主
                options.from = walletAddress
                //ガス単価
                options.gasPrice = .automatic
                //ガス使用量上限
                options.gasLimit = .automatic
                //トランザクションの中身
                let transaction = contract.write(
                    "fallback",
                    parameters: [AnyObject](),
                    extraData: Data(),
                    transactionOptions: options)!
                
                do{
                    //実際に送信
                    let result = try transaction.send(password: pass)
                    print("成功")
                catch{
                    print("エラー:\(error)")
                    
                    return
                }
                
                
            } catch {
                //エラー処理
                print("ファイルない")
            }
        }
        
```