PythonでSymbol ブロックチェーン上のXYMを送金する。(23年02月)

- 【概要】
symbol-sdk-pythonを使ってXYMを送金したのですが、テストネットは毎回リセットがかかって、EPOCHやら、generationhashやらが変わるので、ノードにアクセスして確認できるようにしました。

- 【環境・前提条件】

windows10
Python 3.10.9
symbol-sdk-python 3.0.3

- 【コード(testnet_send_xym.py)】
先人の方々の内容とほぼ一緒です。
必要なライブラリはpip install <ライブラリ名>でインストール。

```from binascii import unhexlify
from symbolchain.CryptoTypes import PrivateKey
from symbolchain.symbol.KeyPair import KeyPair
from symbolchain.facade.SymbolFacade import SymbolFacade
import http.client
import datetime
import requests
import json

#XYM送信に必要な項目を入力
node = "sym-test-04.opening-line.jp"
private_key = "testnet privetekey"
recipient_address = "testnet address"
fee = 0.1
amount = 1
msg_txt = "Hello symbol!"

#ノードからプロパティを取得
def get_node_properties():
        """
        network type, epock ajustment, currency mosaic id, generation hashを取得する
        """
        node_url = "https://" + node+ ":3001"
        node_url_properties = node_url + "/network/properties"
        response = requests.get(node_url_properties)
        if response.status_code != 200:
            raise Exception("status code is {}".format(response.status_code))
        contents = json.loads(response.text)
        network = str(contents["network"]["identifier"].replace("'", ""))
        epoch_adjustment = int(contents["network"]["epochAdjustment"].replace("s", ""))
        currency_mosaic_id = int(contents["chain"]["currencyMosaicId"].replace("'", ""), 16)
        generation_hash_seed = str(contents["network"]["generationHashSeed"].replace("'", ""))
        return network, epoch_adjustment,currency_mosaic_id, generation_hash_seed, node_url

#nodeをmainnetノードに変えればにプロパティも変わる
NETWORK_TYPE = get_node_properties()[0]
EPOCH_ADJUSTMENT = get_node_properties()[1]
MOSAICID = get_node_properties()[2]
NODE_URL = get_node_properties()[4]


#GENARATION_HASHは送金に利用しないが、確認用。
GENERATOIN_HASH = get_node_properties()[3]

#各プロパティ確認用
print("Network type => " + str(NETWORK_TYPE))
print("Epoch ajustment => " + str(EPOCH_ADJUSTMENT))
print("Mosaic ID => " + str(hex(MOSAICID)).upper())
print("Generation hash => " + str(GENERATOIN_HASH))
print("Using node url => " + str(NODE_URL))

#秘密鍵から公開鍵を導出
unhex_privatekey = unhexlify(private_key)
privatekey = PrivateKey(unhex_privatekey)
keypair = KeyPair(privatekey)
publickey = keypair.public_key
#print(str(publickey))

#coice testnet or mainnet
facade = SymbolFacade(NETWORK_TYPE)

#アドレスを導出
address = facade.network.public_key_to_address(publickey)
print("Your address => " + str(address))

deadline = (int((datetime.datetime.today() + datetime.timedelta(hours=2)).timestamp()) - EPOCH_ADJUSTMENT) * 1000

#トランザクションを生成
tx = facade.transaction_factory.create({
    'type': 'transfer_transaction',
    'signer_public_key': publickey,
    'fee': int(fee * 1000000),
    'deadline': deadline,
    'recipient_address': recipient_address,
    'mosaics': [{'mosaic_id':MOSAICID, 'amount':int(amount * 1000000)}],
    'message': bytes(1) + msg_txt.encode('utf8')
})

#署名＆ペイロード生成(v3.0.3から書き方変更)
signature = facade.sign_transaction(keypair, tx)
json_payload = facade.transaction_factory.attach_signature(tx, signature)

#ネットワークへアナウンス
headers = {'Content-type': 'application/json'}
conn = http.client.HTTPConnection(node, 3000)
conn.request("PUT", "/transactions", json_payload, headers)
responce = conn.getresponse()
print(responce.status, responce.reason)

#確認
hash = facade.hash_transaction(tx)
print(get_node_properties()[4] + "/transactionStatus/" + str(hash))

"""
MEMO
pip show symbol-sdk-python でライブラリのインストール先を調べる
```
testnetの場合、generationhashがライブラリ内のファイルにあるので、うまくいかないときは調べてみると良いかも。
参照元参考:
/Local/Programs/Python/Python310/Lib/site-packages/symbolchain/symbol/Network.py


- 【ターミナル出力】
無事送金出来ました。
```
Network type => testnet
Epoch ajustment => 1667250467
Mosaic ID => 0X72C0212E67A08BCE
Generation hash => 49D6E1CE276A85B70EAFE52349AACCA389302E7A9754BCF1221E79494FC665A4
Using node url => https://sym-test-04.opening-line.jp:3001
Your address => TDT*****************BDEIVXYDXMQ
202 Accepted
https://sym-test-04.opening-line.jp:3001/transactionStatus/A6D9***********8E02
```

- 【コード(mainnet)】
node・privatekey・recipient_addressを変えればmainnet用になります。
```
node = "mainnet node"
private_key = "mainnet privatekey"
recipient_address = "mainnet address"
```

- 【引用リンク】

XYM送金記事：
https://qiita.com/nem_takanobu/items/f3c02caa17ad385b6155

SDK3.0.3での変更点：
https://qiita.com/kurikou_XymCity/items/ab9c9475c363c95930d6

ノード情報取得：
https://github.com/curio184/symbol_sdk_python_example/blob/main/example.py