Update 2024/5/31
v3.2.2
でいくつかのクラスや関数が追加されました。これらは分かりやすく、使いやすくすることを目的としていますが、従来の記述方法でも問題ありませんのでご安心ください。v3.2.2
に追加されたクラス、関数について解説しており、すでに Symbol に対しての知識がある方を対象にしています。import { SymbolFacade, descriptors, models, generateMosaicId, generateNamespaceId, metadataGenerateKey, } from 'symbol-sdk/symbol' import { PrivateKey, PublicKey, utils } from 'symbol-sdk' const facade = new SymbolFacade('testnet')
const aliceAccount = facade.createAccount(PrivateKey.random())
const bobAccount = facade.createAccount( new PrivateKey('5DB8324E7EB83E7665D500B014283260EF312139034E86DFB7EE736503EA****') )
const bobPublicAccount = facade.createPublicAccount( new PublicKey('4C4BD7F8E1E1AC61DB817089F9416A7EDC18339F06CDC851495B271533FAD13B') )
const aliceAddress = aliceAccount.address.toString() const bobAddress = bobPublicAccount.address.toString()
const encoded = aliceAccount .messageEncoder() .encode(bobPublicAccount.publicKey, new TextEncoder().encode('hello, symbol!'))
const decoded = bobAccount.messageEncoder().tryDecode(alicePublicAccount.publicKey, encoded)
encoded
はUint8Array
です。受け渡しの際は、hexString に変換してください。また復号の際はUint8Array
に変換してください。const encodedHex = utils.uint8ToHex(encoded) const encodedBytes = utils.hexToUint8(encodedHex)
const transaction = facade.transactionFactory.create({ type: 'transfer_transaction_v1', signerPublicKey: aliceAccount.keyPair.publicKey, recipientAddress: bobPublicAccount.address, mosaics: [ { mosaicId: 0x72c0212e67a08bcen, amount: 1_000000n, }, ], message: `\0Hello, Symbol!!`, fee: 1_000000n, new NetworkTimestamp(facade.network.fromDatetime(new Date())).addHours(2).timestamp, })
TypeScript
においてcreate()
の引数の型はobject
であるため、key に何を指定すればいいか分からない、value の型が分からないなどの問題がありました。TransferTransaction
を元に説明します。const transferTransactionDescripter = new descriptors.TransferTransactionV1Descriptor( bobPublicAccount.address, // or new Address('TA5LGYEWS6L2WYBQ75J2DGK7IOZHYVWFWRLOFWI'), [ new descriptors.UnresolvedMosaicDescriptor( new models.UnresolvedMosaicId(0x72c0212e67a08bcen), new models.Amount(1_000000n) ), ], `\0Hello, Symbol!!` ) const transferTransaction = facade.createTransactionFromTypedDescriptor( transferTransactionDescripter, aliceAccount.publicKey, 100, 3600 ) const signature = aliceAccount.signTransaction(transaction) const payload = facade.transactionFactory.static.attachSignature(transaction, signature)
descriptors
を使用してdescriptor
を作成します。この時、引数の型は明確です。
続いてdescriptor
を元にcreateTransactionFromTypedDescriptor()
によってトランザクションを作成します。createTransactionFromTypedDescriptor()
の引数についてdescriptor
transferTransaction.fee = new models.Amount(0xffffffffn)
new Date()
にて取得した現在時刻を元にデッドラインを設定しています。多少のズレが生じる可能性があるためネットワークから取得するなど厳格に設定したい場合などは以下で対応可能です。transferTransaction.deadline = new models.Timestamp(0xffffffffn)
String
で設定できますが、生データの場合はUint8Array
で渡してください。\0
を追加する以下が簡単です。const message = `\0ここにテキスト`
const address = Address.fromNamespaceId( new models.NamespaceId(generateNamespaceId('namespace_name')), facade.network.identifier )
const transferTransactionDescripterFromAlice = new descriptors.TransferTransactionV1Descriptor( bobPublicAccount.address, [ new descriptors.UnresolvedMosaicDescriptor( new models.UnresolvedMosaicId(0x72c0212e67a08bcen), new models.Amount(1_000000n) ), ], `\0from alice` ) const transferTransactionDescripterFromBob = new descriptors.TransferTransactionV1Descriptor( aliceAccount.address, [ new descriptors.UnresolvedMosaicDescriptor( new models.UnresolvedMosaicId(0x72c0212e67a08bcen), new models.Amount(1_000000n) ), ], `\0from bob` ) const embeddedTransactions = [ facade.createEmbeddedTransactionFromTypedDescriptor(transferTransactionDescripterFromAlice, aliceAccount.publicKey), facade.createEmbeddedTransactionFromTypedDescriptor(transferTransactionDescripterFromBob, bobPublicAccount.publicKey), ] const aggregateTransactionDescriptor = new descriptors.AggregateCompleteTransactionV2Descriptor( facade.static.hashEmbeddedTransactions(embeddedTransactions), embeddedTransactions ) const aggregateTransaction = facade.createTransactionFromTypedDescriptor( aggregateTransactionDescriptor, aliceAccount.publicKey, 100, 3600, 1 // ここで連署者の数を設定する ) const signature = aliceAccount.signTransaction(aggregateTransaction) const payload = facade.transactionFactory.static.attachSignature(aggregateTransaction, signature)
const aggregateTransactionDeserealized = facade.transactionFactory.static.deserialize( aggregateTransaction.serialize() ) as models.AggregateCompleteTransactionV2 const bobCosignature = bobAccount.cosignTransaction(aggregateTransactionDeserealized) aggregateTransactionDeserealized.cosignatures.push(bobCosignature) const payload = JSON.stringify({ payload: utils.uint8ToHex(aggregateTransactionDeserealized.serialize()), })
descriptor
をそれぞれ作成し、AggregateCompleteTransactionV2Descriptor()
の引数とします。createTransactionFromTypedDescriptor()
の第五引数で連署者の人数を設定します。const mosaicNonce = 0x1111 const mosaicId = generateMosaicId(aliceAccount.address, mosaicNonce) const mosaicDefinitionDescriptor = new descriptors.MosaicDefinitionTransactionV1Descriptor( new models.MosaicId(mosaicId), new models.BlockDuration(0n), new models.MosaicNonce(mosaicNonce), new models.MosaicFlags(models.MosaicFlags.TRANSFERABLE.value + models.MosaicFlags.SUPPLY_MUTABLE.value), 0 ) const mosaicSupplyChangeDescriptor = new descriptors.MosaicSupplyChangeTransactionV1Descriptor( new models.UnresolvedMosaicId(mosaicId), new models.Amount(1000n), models.MosaicSupplyChangeAction.INCREASE ) const mosaicEmbeddedTransactions = [ facade.createEmbeddedTransactionFromTypedDescriptor(mosaicDefinitionDescriptor, aliceAccount.publicKey), facade.createEmbeddedTransactionFromTypedDescriptor(mosaicSupplyChangeDescriptor, aliceAccount.publicKey), ] const mosaicAggregateDescriptor = new descriptors.AggregateCompleteTransactionV2Descriptor( facade.static.hashEmbeddedTransactions(mosaicEmbeddedTransactions), mosaicEmbeddedTransactions ) const mosaicAggregateTransaction = facade.createTransactionFromTypedDescriptor( mosaicAggregateDescriptor, aliceAccount.publicKey, 100, 3600 ) const signature = aliceAccount.signTransaction(mosaicAggregateTransaction) const payload = facade.transactionFactory.static.attachSignature(mosaicAggregateTransaction, signature)
const metadata = new TextEncoder().encode('metadata') const accountMetadataTransactionDescriptor = new descriptors.AccountMetadataTransactionV1Descriptor( aliceAccount.address, metadataGenerateKey('test'), metadata.byteLength, metadata ) const accountMetadataEmbeddedTransactions = [ facade.createEmbeddedTransactionFromTypedDescriptor(accountMetadataTransactionDescriptor, aliceAccount.publicKey), ] const accountMetadataAggregateDescriptor = new descriptors.AggregateCompleteTransactionV2Descriptor( facade.static.hashEmbeddedTransactions(accountMetadataEmbeddedTransactions), accountMetadataEmbeddedTransactions ) const accountMetadataAggregateTransaction = facade.createTransactionFromTypedDescriptor( accountMetadataAggregateDescriptor, aliceAccount.publicKey, 100, 3600 ) const signature = aliceAccount.signTransaction(accountMetadataAggregateTransaction) const payload = facade.transactionFactory.static.attachSignature(accountMetadataAggregateTransaction, signature)
metadataGenerateKey()
という関数が新たに作成されました。メタデータは String 型でも受付けますが、Uint8Array でのサイズを指定する必要があるため、上記のようにUint8Array
に変換して渡すことをおすすめします。const namespaceId = new models.NamespaceId(generateNamespaceId('alice_namespace')) const namespaceRegistrationTransactionDescriptor = new descriptors.NamespaceRegistrationTransactionV1Descriptor( namespaceId, models.NamespaceRegistrationType.ROOT, new models.BlockDuration(0x000f0000n), undefined, 'alice_namespace' ) const namespaceAddressAliasTransactionDescriptor = new descriptors.AddressAliasTransactionV1Descriptor( namespaceId, aliceAccount.address, models.AliasAction.LINK ) const namespaceEmbeddedTransactions = [ facade.createEmbeddedTransactionFromTypedDescriptor( namespaceRegistrationTransactionDescriptor, aliceAccount.publicKey ), facade.createEmbeddedTransactionFromTypedDescriptor( namespaceAddressAliasTransactionDescriptor, aliceAccount.publicKey ), ] const namespaceAggregateDescriptor = new descriptors.AggregateCompleteTransactionV2Descriptor( facade.static.hashEmbeddedTransactions(namespaceEmbeddedTransactions), namespaceEmbeddedTransactions ) const namespaceAggregateTransaction = facade.createTransactionFromTypedDescriptor( namespaceAggregateDescriptor, aliceAccount.publicKey, 100, 3600 ) const signature = aliceAccount.signTransaction(namespaceAggregateTransaction) const payload = facade.transactionFactory.static.attachSignature(namespaceAggregateTransaction, signature)
ex) 987E8740D1B46E53274F79F447F8EABE628EAB33D1134837
const address = Address.fromDecodedAddressHexString('987E8740D1B46E53274F79F447F8EABE628EAB33D1134837')
undefind
const namespaceAddress = Address.fromDecodedAddressHexString('99D63C374D96D7ACAE000000000000000000000000000000') const namespaceId = namespaceAddress.toNamespaceId()
fetch(`http://NODE:3000/namespaces/${namespaceId?.toString().substring(2)}`) .then((response) => response.json()) .then((data) => { console.log('Success:', data) }) .catch((error) => { console.error('Error:', error) })
const requestParameters = { namespaceIds: [namespaceId?.toString().substring(2)], } const headerParameters = { 'Content-Type': 'application/json', } const body = JSON.stringify(requestParameters) fetch('http://NODE:3000/namespaces/names', { method: 'POST', headers: headerParameters, body: body, }) .then((response) => response.json()) .then((data) => { console.log('Success:', data) }) .catch((error) => { console.error('Error:', error) })
const bip32 = new Bip32() const mnemonic = bip32.random() console.log(mnemonic)
const bip32Node = bip32.fromMnemonic(mnemonic, 'password') console.log(bip32Node.privateKey)
number[]
を渡します。三番目がアカウントなので複数取得する場合は以下のようにします。for (let i = 0; i < 10; i++) { const child = bip32Node.derivePath([44, 4343, i, 0, 0]).privateKey console.log(`child${i}: ${child}`) }
transaction
をserialize()
して使う、もしくはペイロードを hex で受け取った場合は、utils.hexToUint8()
でUint8Array
に変換してください。models.TransactionFactory.deserialize(transaction.serialize()) facade.transactionFactory.static.deserialize(transaction.serialize()) const uint8Payload = utils.hexToUint8(payload)