Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
10
Help us understand the problem. What is going on with this article?
@nem_takanobu

Symbolブロックチェーンで一人が複数人に送金するトランザクションをPythonで作成する

今回からPythonでアグリートトランザクションを実行してみます。
前回のこの記事を先にお読みください。

今回は一人が複数人に送金する場合を想定します。

インポート
from binascii import unhexlify
from symbolchain.core.CryptoTypes import PrivateKey
from symbolchain.core.sym.KeyPair import KeyPair
from symbolchain.core.facade.SymFacade import SymFacade

facade = SymFacade('public_test')

送金者の生成
b = unhexlify("896E43895B908AF5847ECCB2645543751D94BD87E71058B003417FED5123****")

alicePrikey = PrivateKey(b)
aliceKeypair = KeyPair(alicePrikey)
alicePubkey = aliceKeypair.public_key
aliceAddress = facade.network.public_key_to_address(alicePubkey)
str(aliceAddress)

送信者としてAliceアカウントを秘密鍵から生成します。

受信者の生成
bobPrikey = PrivateKey.random()
bobKeypair = SymFacade.KeyPair(bobPrikey)
bobPubkey = bobKeypair.public_key
bobAddress = facade.network.public_key_to_address(bobPubkey)

carolPrikey = PrivateKey.random()
carolKeypair = SymFacade.KeyPair(carolPrikey)
carolPubkey = carolKeypair.public_key
carolAddress = facade.network.public_key_to_address(carolPubkey)

受信者としてBob,Carolアカウントを新規に作成します。

トランザクション作成
msg = 'test'
bobTx = facade.transaction_factory.create_embedded({
    'type': 'transfer',
    'signer_public_key': alicePubkey,
    'recipient_address': bobAddress,
    'message': bytes(1) + msg.encode('utf8')
})

carolTx = facade.transaction_factory.create_embedded({
    'type': 'transfer',
    'signer_public_key': alicePubkey,
    'recipient_address': carolAddress,
    'message': bytes(1) + msg.encode('utf8')
})

2種類のトランザクションを作成します。受信者はそれぞれBob,Carolですが、送信者はAlice一人です。

マークルハッシュの作成
from symbolchain.core.sym.MerkleHashBuilder import MerkleHashBuilder
from symbolchain.core.CryptoTypes import Hash256
import sha3

hash_builder = MerkleHashBuilder()
hash_builder.update(Hash256(sha3.sha3_256(bobTx.serialize()).digest()))
hash_builder.update(Hash256(sha3.sha3_256(carolTx.serialize()).digest()))
merkle_hash = hash_builder.final()

複数のトランザクションで構成されるため、それぞれのトランザクションハッシュからアグリゲートトランザクションのハッシュを導出しておきます。

アグリゲートトランザクションの作成

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

aggregate = facade.transaction_factory.create({
    'type': 'aggregateComplete',
    'signer_public_key': alicePubkey,
    'fee': 1000000,
    'deadline': deadline,
    'transactions_hash': merkle_hash,
    'transactions': [bobTx,carolTx]
})

signature = facade.sign_transaction(aliceKeypair, aggregate)
aggregate.signature = signature.bytes

先ほど作成したトランザクションを配列に詰めてアグリゲートトランザクションを作成して署名します。

ネットワークへアナウンス
from binascii import hexlify
payload = {"payload": hexlify(aggregate.serialize()).decode('utf8').upper()}

import json
json = json.dumps(payload)

headers = {'Content-type': 'application/json'}
import http.client

conn = http.client.HTTPConnection("sym-test-01.opening-line.jp",3000)
conn.request("PUT", "/transactions", json,headers)

response = conn.getresponse()
print(response.status, response.reason)

署名したトランザクションをJSON化してネットワークに通知します。

確認
hash = facade.hash_transaction(aggregate)
print('https://sym-test-01.opening-line.jp:3001/transactionStatus/' + str(hash))
全ソースコード
from binascii import unhexlify
from symbolchain.core.CryptoTypes import PrivateKey
from symbolchain.core.sym.KeyPair import KeyPair
from symbolchain.core.facade.SymFacade import SymFacade

facade = SymFacade('public_test')

b = unhexlify("896E43895B908AF5847ECCB2645543751D94BD87E71058B003417FED5123****")

alicePrikey = PrivateKey(b)
aliceKeypair = KeyPair(alicePrikey)
alicePubkey = aliceKeypair.public_key
aliceAddress = facade.network.public_key_to_address(alicePubkey)
str(aliceAddress)


bobPrikey = PrivateKey.random()
bobKeypair = SymFacade.KeyPair(bobPrikey)
bobPubkey = bobKeypair.public_key
bobAddress = facade.network.public_key_to_address(bobPubkey)

carolPrikey = PrivateKey.random()
carolKeypair = SymFacade.KeyPair(carolPrikey)
carolPubkey = carolKeypair.public_key
carolAddress = facade.network.public_key_to_address(carolPubkey)


msg = 'test'
bobTx = facade.transaction_factory.create_embedded({
    'type': 'transfer',
    'signer_public_key': alicePubkey,
    'recipient_address': bobAddress,
    'message': bytes(1) + msg.encode('utf8')
})

carolTx = facade.transaction_factory.create_embedded({
    'type': 'transfer',
    'signer_public_key': alicePubkey,
    'recipient_address': carolAddress,
    'message': bytes(1) + msg.encode('utf8')
})

from symbolchain.core.sym.MerkleHashBuilder import MerkleHashBuilder
from symbolchain.core.CryptoTypes import Hash256
import sha3

hash_builder = MerkleHashBuilder()
hash_builder.update(Hash256(sha3.sha3_256(bobTx.serialize()).digest()))
hash_builder.update(Hash256(sha3.sha3_256(carolTx.serialize()).digest()))
merkle_hash = hash_builder.final()

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

aggregate = facade.transaction_factory.create({
    'type': 'aggregateComplete',
    'signer_public_key': alicePubkey,
    'fee': 1000000,
    'deadline': deadline,
    'transactions_hash': merkle_hash,
    'transactions': [bobTx,carolTx]
})

signature = facade.sign_transaction(aliceKeypair, aggregate)
aggregate.signature = signature.bytes


from binascii import hexlify
payload = {"payload": hexlify(aggregate.serialize()).decode('utf8').upper()}

import json
jsonPayload = json.dumps(payload)

headers = {'Content-type': 'application/json'}
import http.client

conn = http.client.HTTPConnection("sym-test-01.opening-line.jp",3000)
conn.request("PUT", "/transactions", jsonPayload ,headers)

response = conn.getresponse()
print(response.status, response.reason)

hash = facade.hash_transaction(aggregate)
print('http://sym-test-01.opening-line.jp:3000/transactionStatus/' + str(hash))


10
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
nem_takanobu
ブロックチェーンはNEM、機械学習はPyTorchが好きです。最近はガウス過程(MCMC、GPLVM)を勉強中。経産省・IPA認定ITストラテジスト

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
10
Help us understand the problem. What is going on with this article?