『symbol-sdk-python 3.0.3』の旧Verからの仕様変更点とハマりどころメモ

# 概要

先日公開した[投げXYMボタン](https://qiita.com/kurikou_XymCity/items/b0836c11629256fd397d)を作った時に、SymbolブロックチェーンのPythonのSDKを触ったんですが、旧Verから微妙に仕様が変わっていたり、少し苦戦したポイントがあったので参考にメモを残そうと思います。

# 対象のSDKバージョン

今回は、[symbol-sdk-python 3.0.3](https://pypi.org/project/symbol-sdk-python/)を前提とします。旧Verと大部分の書き方は変わってないんですが、微妙～に細かく仕様が変わってる部分があります。以下、主な変更点とハマったポイントをまとめます。

# 変更点1. トランザクション生成処理の引数の仕様

## トランザクションタイプの指定方法

XYMを転送するトランザクションを作成する場合、従来は`'type':'transfer'`と指定していたところ、`'type':'transfer_transaction'`に変更。
```python

        tx2 = self._facade.transaction_factory.create({
            # 'transfer'　→ 'transfer_transaction'
            'type': 'transfer_transaction', 
            'signer_public_key': self._km.get_my_pubkey(),
            'fee': fee,
            'deadline': deadline,
            'recipient_address': recipient_address,
            'mosaics': mosaics,
            'message': bytes(1) + msg_txt.encode('utf8')
        })

```

## mosaicsの指定もタプルから辞書型に変更

旧Verではタプル型の配列で渡していたところ、辞書型の配列で渡すように変更。前のVerでは`mosaics: [(0x091F837E059AE13C, 1000000)]`というようにタプルで渡せていたのが、最近から辞書型に変わったようです。

```python
    mosaics =  [{'mosaic_id':0x091F837E059AE13C],'amount':int(amount * 1000000)}]
```

# 変更点2. 署名とペイロード生成周りの処理

旧Verでは、トランザクションへの署名と、ペイロードの生成を以下のように書いていましたが、最近のVerでは署名の埋め込みとペイロード生成までまとめて行ってくれる関数が実装されたようです。

旧Verでの書き方
```python
        signature = facade.sign_transaction(key_pair, aggregate_transaction)
        tx.signature = signature.bytes
        # ペイロードを自前で生成＆Json化
        payload = {"payload": hexlify(tx.serialize()).decode('utf8').upper()}
        json_payload = json.dumps(payload)
```

今回のVer(3.0.3)での書き方

```python
        signature = self._facade.sign_transaction(self._keypair, tx)
        json_payload = self._facade.transaction_factory.attach_signature(tx, signature)
```


# その他ハマったポイント紹介

SDKの微妙な仕様変更箇所と、過去の解説記事とのギャップをひとつずつ修正して、ようやくPythonでトランザクションが飛ばせた！（202が返ってきた！）…けど着金しない…なんでだ…。とかなり苦戦したポイントが有ったので最後に紹介します。

[nem Japan UserGroup](https://t.co/BL0KGSwwfM)というSymbol開発者の方々が集うコミュニティで、有識者の方にアドバイスをもらってようやく解決しましたが、分かればなんと単純、トランザクションを飛ばす時に指定したモザイクID（トークンのID）と、トランザクションの有効期限の計算が間違っていました。

## ①過去の記事と現在で、テストネットのモザイクIDが変わっていた

PythonのSymbol開発の記事を検索すると、2021年頃に書かれたものが多いですが、その当時と今ではモザイクIDが変更になっている場合があるので注意が必要です。安易にコピペで試そうとしても、そのままでは動きません（涙）

2021年頃のテストネットXYMのモザイクIDは`0x091F837E059AE13C`ですが、この記事を書いている現時点では`0x3A8416DB2D53B6C8`に変更になっていたようです。全く気が付かず、コミュニティの方に相談して教えて頂くまで、一人で悩みまくってしまいました…。

## ②同じく、ネットワークの基準時刻(birthtime)が変わってた

トランザクションの有効期限を設定する際に、deadlineというパラメータを指定する必要があります。この時、現在時刻とネットワークの基準時刻(最初のブロックが生成された時刻：birthtime）の差分から有効期限を算出するのですが、この「ネットワークの基準時刻」が合っているかも注意が必要です。

こちらも参考までに記載すると、当時のテストネットの基準時刻は`1616694977`でしたが、今のテストネットの正しい基準時刻は`1637848847`になっています。（どちらもUNIXTIME）

# 教訓

- **安易に過去の技術記事をコピペしない**
- **最新の開発情報・仕様をきちんとウォッチする**

Symbol開発者の[nem_takanobu](https://qiita.com/nem_takanobu)さんが、せっかく[最新の仕様情報やネットワークプロパティ等の設定情報を細かくまとめて公開](https://qiita.com/nem_takanobu/items/4f50e5740318d92d7dcb)してくださっているのに、このような凡ミスにハマってしまい大いに反省しております。

私が今回ハマったテストネットのモザイクID・基準時刻のプロパティについてもバッチリ正しい情報が載っており、極めてお恥ずかしい限りです…。もっと勉強に励みます（土下座）

# まとめ

SDKの細かい変更点と、自らの恥ずかしい失敗事例を紹介しました。今回は自らの勉強不足もあり少しハマってしまいましたが、基本的には提供されているSDKを素直に叩けばPythonでもブロックチェーンプログラミングが出来ますので、少しPythonが触れる人なら誰でもチャレンジできると思います。

また、Symbolを通したブロックチェーンアプリ開発にご興味ある方は、先程紹介したnem_takanobuさんの開発情報まとめ記事を必読すること、そしてぜひ開発者コミュニティのDiscodeに参加することを強くオススメ致します。アプリ開発だけでなく、暗号学やインフラ周り、税制やマーケティング・企画まで幅広く活発な議論が行われており、とても勉強になります！

### Symbol関連の開発者はフォロー必須です！
- @nem_takanobu さん
- [Hello Symbol Blockchain! 2022年5月時点での開発関連情報まとめ](https://qiita.com/nem_takanobu/items/4f50e5740318d92d7dcb)

### Symbol関連の開発者コミュニティ(Discode)はこちら
- [nem Japan UserGroup](https://t.co/BL0KGSwwfM)

# 参考記事

- [PythonでSymbolブロックチェーンの送金プログラムを書いてみる。](https://qiita.com/nem_takanobu/items/f3c02caa17ad385b6155)
- [[Symbol] Pythonでxymを送金する](https://qiita.com/nobu_kyutech/items/049971f8b82cc9a055e8)
- [20 JUL GETTING STARTED WITH SYMBOL IN PYTHON – PART 4](https://symbolblog.com/developer-guides/getting-started-with-symbol-in-python-part-4/)

Symbol開発の入門にはこちらがオススメです。

https://github.com/xembook/quick_learning_symbol


# コード全文
`symbol-sdk-python 3.0.3`で、Bluetoothボタンを押した時にトランザクションを飛ばす（投げXYM）するコードの全文をGithubで公開中です。今回の記事の内容と合わせてどうぞ。

[ワンポチでブロックチェーンにデータを刻むボタンを作ってみた](https://qiita.com/kurikou_XymCity/items/b0836c11629256fd397d)

https://github.com/kurikou02/XymSendButton