15
5

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 1 year has passed since last update.

nem / symbolAdvent Calendar 2022

Day 5

Symbol SDK JS v3 でTransferTransaction

Last updated at Posted at 2022-12-04

SDK v3 のインストールがまだの場合はコチラ

  • Symbol SDK JS v3 でAggregateTransaction

SDKがインストールできたらTransferTransactionを送ってみます。
v2との違いなど簡単に解説できたらと思います。

TransferTransaction

※インストールの続きなのでそうじゃない場合はここは不要

cd ../../../
touch transfer.js

※ここから本題
まずは全文貼り付けますが後でちょっと解説します。コピペだけでいいよって人用。

transfer.js
import sdk from './sdk/javascript/src/index.js';
import fetch from 'node-fetch';

const netWork = new sdk.symbol.Network(
    'testnet',
	0x98,
	new Date(Date.UTC(2022, 9, 31, 21, 7, 47)),
	new sdk.Hash256('49D6E1CE276A85B70EAFE52349AACCA389302E7A9754BCF1221E79494FC665A4')
)

const facade = new sdk.facade.SymbolFacade(netWork);
const alicePrivateKey = new sdk.PrivateKey('ALICE_PRIVATE_KEY');
const aliceKeyPair = new sdk.symbol.KeyPair(alicePrivateKey);
const aliceAddress = facade.network.publicKeyToAddress(aliceKeyPair.publicKey);
const alicePlainAddress = new sdk.symbol.Address(aliceAddress).toString();

const deadline = new sdk.symbol.NetworkTimestamp(facade.network.fromDatetime(Date.now())).addHours(2).timestamp;

const transaction = facade.transactionFactory.create({
    type: 'transfer_transaction_v1',
    signerPublicKey: aliceKeyPair.publicKey,
    recipientAddress: 'BOB_PLAIN_ADDRESS',
    mosaics: [
		{ 
            mosaicId: 0x72C0212E67A08BCEn,
            amount: 1_000000n 
        }
	],
    message: [0,...(new TextEncoder('utf-8')).encode('Hello, Symbol!!')],
    fee: 1_000000n,
    deadline,
});

const aliceSignature = facade.signTransaction(aliceKeyPair, transaction);
const jsonPayload = facade.transactionFactory.constructor.attachSignature(transaction, aliceSignature);

(async()=> {
    const res = await fetch("NODE_URL", {
        method: 'put',
        body: jsonPayload  ,
        headers: {'Content-Type': 'application/json'}
    })
    console.log(await res.json());
})();

facade作成

const netWork = new sdk.symbol.Network(
    'testnet',
	0x98,
	new Date(Date.UTC(2022, 9, 31, 21, 7, 47)),
	new sdk.Hash256('49D6E1CE276A85B70EAFE52349AACCA389302E7A9754BCF1221E79494FC665A4')
)

const facade = new sdk.facade.SymbolFacade(netWork);

今回はテストネットを使用しており先日のアップデートでテストネットが新しくなったのですが、epoc timeやgeneration hashなどがまだSDKにハードコーディングされていないため自作します。MainNetの場合はこれだけでいいです。

const facade = new sdk.facade.SymbolFacade(sdk.symbol.Network.MAINNET);

アカウント作成

const alicePrivateKey = new sdk.PrivateKey('ALICE_PRIVATE_KEY');
const aliceKeyPair = new sdk.symbol.KeyPair(alicePrivateKey);
const aliceAddress = facade.network.publicKeyToAddress(aliceKeyPair.publicKey);
const alicePlainAddress = new sdk.symbol.Address(aliceAddress).toString();

作成したいトランザクションによりますがv2との違いの一つで、いわゆるv2でのAccountクラスはprivateKeyから作成します。AddressクラスやPlainAddress(Nから始まる39桁文字列)は公開鍵から作成できますがこの辺はテンプレで覚えていると良いかも。秘密鍵が分からず公開鍵からアドレスなどを取得したい場合は以下です。

const bobPublicKey = new sdk.PublicKey(sdk.utils.hexToUint8('hex_public_key'));
const bobAddress = facade.network.publicKeyToAddress(bobPublicKey);
const bobPlainAddress = new sdk.symbol.Address(bobAddress).toString();
console.log(bobPlainAddress);

deadline

現在時刻から2時間後の場合

const deadline = new sdk.symbol.NetworkTimestamp(facade.network.fromDatetime(Date.now())).addHours(2).timestamp;

Transaction構築

const transaction = facade.transactionFactory.create({
    type: 'transfer_transaction_v1',
    signerPublicKey: aliceKeyPair.publicKey,
    recipientAddress: 'BOB_PLAIN_ADDRESS',
    mosaics: [
		{ 
            mosaicId: 0x72C0212E67A08BCEn,
            amount: 1_000000n 
        }
	],
    message: [0,...(new TextEncoder('utf-8')).encode('Hello, Symbol!!')],
    fee: 1_000000n,
    deadline,
});
type: 'transfer_transaction_v1',

Transactionのタイプです。他のトランザクションでの文字列を知りたい場合は、

ここを覗くと良いかと。文字列からTranasctionTypeを返す箇所。

signerPublicKey: aliceKeyPair.publicKey,

ここの公開鍵はhex stringでもOKです。SDK内でいい感じにパースしてくれます。

signerPublicKey: '13B00FBB13C7644E13BD786F0EA4F97820022A2606759793A5D3525A03F92A2F',

同じくアドレスも

recipientAddress: bobAddress,
or
recipientAddress: 'TAUYF774MZWLBEUI7S2LR6BA5CYLL53QSMDVV3Y',
mosaics: [
		{ 
            mosaicId: 0x72C0212E67A08BCEn,
            amount: 1_000000n 
        }
	],

モザイクIDはBigIntなので頭に0x、お尻にnを付けてあげれば数値になります。amountも同じくBigIntですが1_000000n1000000nも同じ。桁数が分かりやすいだけ。

message: [0,...(new TextEncoder('utf-8')).encode('Hello, Symbol!!')],

メッセージはエクスプローラーの仕様に合わせてエンコードしてからPlainMessageの場合は頭の1byteに0を足してあげる。
シンプルに

message: 'Hello, Symbol!!',

でも構わないがその場合、APIからHexで取得した際にデコードが必要

(new TextDecoder('utf-8')).decode(sdk.utils.hexToUint8('48656C6C6F2C2053796D626F6C2121'));

手数料

手数料はサンプルなので fee: 1_000000nとしましたが、本番では出来る限り低い手数料を望むと思うので、トランザクションのサイズに合わせて後ほど手数料をセットするというのも良いかと思います。

transaction.fee = new sdk.symbol.Amount(BigInt(transaction.size * 100));

100 は手数料乗数でv2だと.setMaxFee(100);の100と同じ。

署名&ペイロード作成

const aliceSignature = facade.signTransaction(aliceKeyPair, transaction);
const jsonPayload = facade.transactionFactory.constructor.attachSignature(transaction, aliceSignature);

v2と感覚的に違うのは署名のトランザクションへのアタッチは自分でやる。attachSignature()はこの後Putする際のJsonを作成し返してくれる。

アナウンス

(async()=> {
    const res = await fetch("NODE_URL", {
        method: 'put',
        body: jsonPayload  ,
        headers: {'Content-Type': 'application/json'}
    })
    console.log(await res.json());
})();

SDKでやってくれるのは基本的にトランザクションのペイロード作成までで、ノードへのアナウンスはfetchでもaxiosでも自分の好きなものを使えば良いです。ここではfetchでやってます。

さいごに

シンプルなTransferTransactionは以上です。

他のトランザクションの作成サンプルは以下にあるので一度見ておくと良いかと思います。ただし、α版なため、まれにそのとおりにしても動かない場合があります。そんな時はDiscordで突っ込むと良いかと思います。SDKに修正があったがサンプルに修正が無い場合があります。

最後までお読みいただきありがとうございました!

15
5
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
15
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?