importjsonimportosimporttimeimporturllib.requestfromsymbolchain.CryptoTypesimportPrivateKeyfromsymbolchain.facade.SymbolFacadeimportSymbolFacadefromsymbolchain.symbol.IdGeneratorimportgenerate_namespace_idfromsymbolchain.symbol.Metadataimport(metadata_generate_key,metadata_update_value)NODE_URL=os.getenv('NODE_URL','https://reference.symboltest.net:3001')print(f'Using node {NODE_URL}')# Helper function to announce a transactiondefannounce_transaction(payload,label):print(f'Announcing {label} to /transactions')request=urllib.request.Request(f'{NODE_URL}/transactions',data=payload.encode(),headers={'Content-Type':'application/json'},method='PUT')withurllib.request.urlopen(request)asannounce_response:print(f' Response: {announce_response.read().decode()}')# Helper function to wait for transaction confirmationdefwait_for_confirmation(tx_hash,label):print(f'Waiting for {label} confirmation...')forattemptinrange(60):time.sleep(1)try:url=f'{NODE_URL}/transactionStatus/{tx_hash}'withurllib.request.urlopen(url)asconfirm_response:status=json.loads(confirm_response.read().decode())print(f' Transaction status: {status["group"]}')ifstatus['group']=='confirmed':print(f'{label} confirmed in {attempt} seconds')returnifstatus['group']=='failed':raiseRuntimeError(f'{label} failed: {status["code"]}')excepturllib.error.HTTPError:print(' Transaction status: unknown')raiseTimeoutError(f'{label} not confirmed after 60 seconds')SIGNER_PRIVATE_KEY=os.getenv('SIGNER_PRIVATE_KEY','0000000000000000000000000000000000000000000000000000000000000000')signer_key_pair=SymbolFacade.KeyPair(PrivateKey(SIGNER_PRIVATE_KEY))facade=SymbolFacade('testnet')signer_address=facade.network.public_key_to_address(signer_key_pair.public_key)print(f'Signer address: {signer_address}')# Get namespace name from environment or use defaultNAMESPACE_NAME=os.getenv('NAMESPACE_NAME','testnamespace')namespace_id=generate_namespace_id(NAMESPACE_NAME)print(f'Namespace name: {NAMESPACE_NAME}')print(f'Namespace ID: {namespace_id} (0x{namespace_id:016X})')try:# Fetch recommended feesfee_path='/network/fees/transaction'print(f'Fetching recommended fees from {fee_path}')withurllib.request.urlopen(f'{NODE_URL}{fee_path}')asresponse:response_json=json.loads(response.read().decode())median_multiplier=response_json['medianFeeMultiplier']minimum_multiplier=response_json['minFeeMultiplier']fee_multiplier=max(median_multiplier,minimum_multiplier)print(f' Fee multiplier: {fee_multiplier}')# --- ADDING NEW METADATA ---print('\n--- Adding new metadata ---')# Define metadata key and valuekey_string=f'description_{int(time.time())}'scoped_metadata_key=metadata_generate_key(key_string)metadata_value='My first namespace'.encode('utf8')# Create the embedded metadata transactionembedded_transaction=(facade.create_embedded_transaction_from_descriptor({'type':'namespace_metadata_transaction_v1','target_address':signer_address,'target_namespace_id':namespace_id,'scoped_metadata_key':scoped_metadata_key,# When creating new metadata, value_size_delta# equals the value length'value_size_delta':len(metadata_value),'value':metadata_value},signer_key_pair.public_key))print('Created embedded metadata transaction:')print(json.dumps(embedded_transaction.to_json(),indent=2))# Build the aggregate transactionembedded_transactions=[embedded_transaction]transaction=facade.create_transaction_from_descriptor({'type':'aggregate_complete_transaction_v3','transactions_hash':facade.hash_embedded_transactions(embedded_transactions),'transactions':embedded_transactions},signer_key_pair.public_key,fee_multiplier,2*60*60)# Sign and generate final payloadsignature=facade.sign_transaction(signer_key_pair,transaction)json_payload=facade.transaction_factory.attach_signature(transaction,signature)# Announce and wait for confirmationtransaction_hash=facade.hash_transaction(transaction)print(f'Built aggregate transaction with hash: {transaction_hash}')announce_transaction(json_payload,'aggregate transaction')wait_for_confirmation(transaction_hash,'aggregate transaction')# --- MODIFYING EXISTING METADATA ---print('\n--- Modifying existing metadata ---')# Fetch current metadata value from networkmetadata_path=(f'/metadata?sourceAddress={signer_address}'f'&targetAddress={signer_address}'f'&scopedMetadataKey={scoped_metadata_key:016X}'f'&targetId={namespace_id:016X}''&metadataType=2')print(f'Fetching current metadata from {metadata_path}')withurllib.request.urlopen(f'{NODE_URL}{metadata_path}')asresponse:response_json=json.loads(response.read().decode())# Get the metadata entryifnotresponse_json['data']:raiseRuntimeError('Metadata entry not found')metadata_entry=response_json['data'][0]['metadataEntry']current_value=bytes.fromhex(metadata_entry['value'])print(f' Current value: {current_value.decode("utf8")}')# XOR the current and new valuesnew_value='Updated namespace'.encode('utf8')update_value=metadata_update_value(current_value,new_value)# Create the update transaction with XOR'd valueembedded_update=facade.create_embedded_transaction_from_descriptor({'type':'namespace_metadata_transaction_v1','target_address':signer_address,'target_namespace_id':namespace_id,'scoped_metadata_key':scoped_metadata_key,# value_size_delta is the difference in length# (can be negative)'value_size_delta':len(new_value)-len(current_value),'value':update_value},signer_key_pair.public_key)print('Created embedded update transaction:')print(json.dumps(embedded_update.to_json(),indent=2))# Build the aggregate for the updateembedded_transactions=[embedded_update]update_transaction=facade.create_transaction_from_descriptor({'type':'aggregate_complete_transaction_v3','transactions_hash':facade.hash_embedded_transactions(embedded_transactions),'transactions':embedded_transactions},signer_key_pair.public_key,fee_multiplier,2*60*60)# Sign and announce the updatesignature=facade.sign_transaction(signer_key_pair,update_transaction)json_payload=facade.transaction_factory.attach_signature(update_transaction,signature)# Announce and wait for confirmationupdate_hash=facade.hash_transaction(update_transaction)print(f'Built aggregate transaction with hash: {update_hash}')announce_transaction(json_payload,'aggregate transaction')wait_for_confirmation(update_hash,'aggregate transaction')exceptExceptionase:print(e)
import{PrivateKey}from'symbol-sdk';import{SymbolFacade,descriptors,generateNamespaceId,metadataGenerateKey,metadataUpdateValue,models}from'symbol-sdk/symbol';constNODE_URL=process.env.NODE_URL||'https://reference.symboltest.net:3001';console.log('Using node',NODE_URL);// Helper function to announce a transactionasyncfunctionannounceTransaction(payload,label){console.log(`Announcing ${label} to /transactions`);constresponse=awaitfetch(`${NODE_URL}/transactions`,{method:'PUT',headers:{'Content-Type':'application/json'},body:payload});console.log(' Response:',awaitresponse.text());}// Helper function to wait for transaction confirmationasyncfunctionwaitForConfirmation(transactionHash,label){console.log(`Waiting for ${label} confirmation...`);for(letattempt=0;60>attempt;attempt++){awaitnewPromise(resolve=>{setTimeout(resolve,1000);});constresponse=awaitfetch(`${NODE_URL}/transactionStatus/${transactionHash}`);if(!response.ok){if(404===response.status){console.log(' Transaction status: unknown');continue;}thrownewError(`HTTP ${response.status}`);}conststatus=awaitresponse.json();console.log(' Transaction status:',status.group);if('confirmed'===status.group){console.log(`${label} confirmed in`,attempt,'seconds');return;}if('failed'===status.group)thrownewError(`${label} failed: ${status.code}`);}thrownewError(`${label} not confirmed after 60 seconds`);}constSIGNER_PRIVATE_KEY=process.env.SIGNER_PRIVATE_KEY||('0000000000000000000000000000000000000000000000000000000000000000');constsignerKeyPair=newSymbolFacade.KeyPair(newPrivateKey(SIGNER_PRIVATE_KEY));constfacade=newSymbolFacade('testnet');constsignerAddress=facade.network.publicKeyToAddress(signerKeyPair.publicKey);console.log('Signer address:',signerAddress.toString());// Get namespace name from environment or use defaultconstNAMESPACE_NAME=process.env.NAMESPACE_NAME||'testnamespace';constnamespaceId=generateNamespaceId(NAMESPACE_NAME);constnamespaceIdHex=namespaceId.toString(16).toUpperCase().padStart(16,'0');console.log('Namespace name:',NAMESPACE_NAME);console.log('Namespace ID:',namespaceId.toString(),`(0x${namespaceIdHex})`);try{// Fetch recommended feesconstfeePath='/network/fees/transaction';console.log('Fetching recommended fees from',feePath);constfeeResponse=awaitfetch(`${NODE_URL}${feePath}`);constfeeJSON=awaitfeeResponse.json();constmedianMultiplier=feeJSON.medianFeeMultiplier;constminimumMultiplier=feeJSON.minFeeMultiplier;constfeeMultiplier=Math.max(medianMultiplier,minimumMultiplier);console.log(' Fee multiplier:',feeMultiplier);// --- ADDING NEW METADATA ---console.log('\n--- Adding new metadata ---');// Define metadata key and valueconstkeyString=`description_${Date.now()}`;constscopedMetadataKey=metadataGenerateKey(keyString);constmetadataValue=newTextEncoder().encode('My first namespace');// Create the embedded metadata transactionconstembeddedTransaction=facade.createEmbeddedTransactionFromTypedDescriptor(newdescriptors.NamespaceMetadataTransactionV1Descriptor(signerAddress,scopedMetadataKey,// When creating new metadata, valueSizeDelta// equals value lengthnewmodels.NamespaceId(namespaceId),metadataValue.length,metadataValue),signerKeyPair.publicKey);console.log('Created embedded metadata transaction:');console.log(JSON.stringify(embeddedTransaction.toJson(),null,2));// Build the aggregate transactionconstembeddedTransactions=[embeddedTransaction];consttransaction=facade.createTransactionFromTypedDescriptor(newdescriptors.AggregateCompleteTransactionV3Descriptor(facade.static.hashEmbeddedTransactions(embeddedTransactions),embeddedTransactions,undefined),signerKeyPair.publicKey,feeMultiplier,2*60*60);// Sign and generate final payloadconstsignature=facade.signTransaction(signerKeyPair,transaction);constjsonPayload=facade.transactionFactory.static.attachSignature(transaction,signature);// Announce and wait for confirmationconsttransactionHash=facade.hashTransaction(transaction).toString();console.log('Built aggregate transaction with hash:',transactionHash);awaitannounceTransaction(jsonPayload,'aggregate transaction');awaitwaitForConfirmation(transactionHash,'aggregate transaction');// --- MODIFYING EXISTING METADATA ---console.log('\n--- Modifying existing metadata ---');// Fetch current metadata value from networkconstscopedKeyHex=scopedMetadataKey.toString(16).toUpperCase().padStart(16,'0');constmetadataPath='/metadata'+`?sourceAddress=${signerAddress}`+`&targetAddress=${signerAddress}`+`&scopedMetadataKey=${scopedKeyHex}`+`&targetId=${namespaceIdHex}`+'&metadataType=2';console.log('Fetching current metadata from',metadataPath);constmetadataResponse=awaitfetch(`${NODE_URL}${metadataPath}`);constmetadataJSON=awaitmetadataResponse.json();// Get the metadata entryif(!metadataJSON.data.length)thrownewError('Metadata entry not found');constmetadataEntry=metadataJSON.data[0].metadataEntry;constcurrentValue=Buffer.from(metadataEntry.value,'hex');console.log(' Current value:',currentValue.toString('utf8'));// XOR the current and new valuesconstnewValue=newTextEncoder().encode('Updated namespace');constupdateValue=metadataUpdateValue(currentValue,newValue);// Create the update transaction with XOR'd valueconstembeddedUpdate=facade.createEmbeddedTransactionFromTypedDescriptor(newdescriptors.NamespaceMetadataTransactionV1Descriptor(signerAddress,scopedMetadataKey,newmodels.NamespaceId(namespaceId),// valueSizeDelta is the difference in length// (can be negative)newValue.length-currentValue.length,updateValue),signerKeyPair.publicKey);console.log('Created embedded update transaction:');console.log(JSON.stringify(embeddedUpdate.toJson(),null,2));// Build the aggregate for the updateconstupdateEmbedded=[embeddedUpdate];constupdateTransaction=facade.createTransactionFromTypedDescriptor(newdescriptors.AggregateCompleteTransactionV3Descriptor(facade.static.hashEmbeddedTransactions(updateEmbedded),updateEmbedded,undefined),signerKeyPair.publicKey,feeMultiplier,2*60*60);// Sign and announce the updateconstupdateSignature=facade.signTransaction(signerKeyPair,updateTransaction);constupdatePayload=facade.transactionFactory.static.attachSignature(updateTransaction,updateSignature);// Announce and wait for confirmationconstupdateHash=facade.hashTransaction(updateTransaction).toString();console.log('Built aggregate transaction with hash:',updateHash);awaitannounceTransaction(updatePayload,'aggregate transaction');awaitwaitForConfirmation(updateHash,'aggregate transaction');}catch(e){console.error(e.message,'| Cause:',e.cause?.code??'unknown');}
//JAVA 21+//DEPS org.symbol:symbol-sdk:3.3.1importjava.io.IOException;importjava.net.URI;importjava.net.http.HttpClient;importjava.net.http.HttpRequest;importjava.net.http.HttpResponse;importjava.net.http.HttpResponse.BodyHandlers;importjava.nio.charset.StandardCharsets;importjava.util.List;importcom.fasterxml.jackson.databind.JsonNode;importcom.fasterxml.jackson.databind.ObjectMapper;importorg.symbol.sdk.CryptoTypes;importorg.symbol.sdk.facade.SymbolFacade;importorg.symbol.sdk.symbol.Address;importorg.symbol.sdk.symbol.IdGenerator;importorg.symbol.sdk.symbol.KeyPair;importorg.symbol.sdk.symbol.Metadata;importorg.symbol.sdk.symbol.SymbolTransactionFactory;importorg.symbol.sdk.symbol.descriptors.*;importorg.symbol.sdk.symbol.models.*;publicfinalclassNamespaceMetadata{privatestaticfinalObjectMapperJSON_MAPPER=newObjectMapper();privatestaticfinalHttpClientHTTP_CLIENT=HttpClient.newHttpClient();privatefinalStringnodeUrl=System.getenv().getOrDefault("NODE_URL","https://reference.symboltest.net:3001");privatefinalSymbolFacadefacade=newSymbolFacade("testnet");// Helper function to announce a transactionprivatevoidannounceTransaction(finalStringpayload,finalStringlabel)throwsIOException,InterruptedException{System.out.printf("Announcing %s to /transactions%n",label);finalHttpRequestrequest=HttpRequest.newBuilder(URI.create(nodeUrl+"/transactions")).header("Content-Type","application/json").PUT(HttpRequest.BodyPublishers.ofString(payload)).build();finalHttpResponse<String>response=HTTP_CLIENT.send(request,BodyHandlers.ofString());System.out.printf(" Response: %s%n",response.body());}// Helper function to wait for transaction confirmationprivatevoidwaitForConfirmation(finalStringtransactionHash,finalStringlabel)throwsIOException,InterruptedException{System.out.printf("Waiting for %s confirmation...%n",label);for(intattempt=0;60>attempt;++attempt){Thread.sleep(1000);finalStringstatusPath="/transactionStatus/"+transactionHash;finalHttpRequeststatusRequest=HttpRequest.newBuilder(URI.create(nodeUrl+statusPath)).GET().build();finalHttpResponse<String>statusResponse=HTTP_CLIENT.send(statusRequest,BodyHandlers.ofString());if(404==statusResponse.statusCode()){System.out.println(" Transaction status: unknown");continue;}if(2!=statusResponse.statusCode()/100)thrownewIOException("HTTP "+statusResponse.statusCode());finalJsonNodestatus=JSON_MAPPER.readTree(statusResponse.body());finalStringgroup=status.get("group").asText();System.out.printf(" Transaction status: %s%n",group);if("confirmed".equals(group)){System.out.printf("%s confirmed in %d seconds%n",label,attempt);return;}if("failed".equals(group))thrownewIOException(String.format("%s failed: %s",label,status.get("code").asText()));}thrownewIOException(String.format("%s not confirmed after 60 seconds",label));}publicstaticvoidmain(finalString[]args){try{newNamespaceMetadata().run();}catch(finalExceptionex){System.out.println(null==ex.getMessage()?ex.toString():ex.getMessage());}}privatevoidrun()throwsIOException,InterruptedException{System.out.printf("Using node %s%n",nodeUrl);finalStringsignerPrivateKey=System.getenv().getOrDefault("SIGNER_PRIVATE_KEY","0".repeat(64));finalKeyPairsignerKeyPair=newKeyPair(newCryptoTypes.PrivateKey(signerPrivateKey));finalAddresssignerAddress=facade.network.publicKeyToAddress(signerKeyPair.getPublicKey());System.out.printf("Signer address: %s%n",signerAddress);// Get namespace name from environment or use defaultfinalStringnamespaceName=System.getenv().getOrDefault("NAMESPACE_NAME","testnamespace");finallongnamespaceId=IdGenerator.generateNamespaceId(namespaceName);System.out.printf("Namespace name: %s%n",namespaceName);System.out.printf("Namespace ID: %s (0x%016X)%n",Long.toUnsignedString(namespaceId),namespaceId);// Fetch recommended feesfinalStringfeePath="/network/fees/transaction";System.out.printf("Fetching recommended fees from %s%n",feePath);finalJsonNodefeeJson=getJson(feePath);finallongfeeMultiplier=Math.max(feeJson.get("medianFeeMultiplier").asLong(),feeJson.get("minFeeMultiplier").asLong());System.out.printf(" Fee multiplier: %d%n",feeMultiplier);// --- ADDING NEW METADATA ---System.out.println("\n--- Adding new metadata ---");// Define metadata key and valuefinalStringkeyString="description_"+System.currentTimeMillis();finallongscopedMetadataKey=Metadata.generateKey(keyString);finalbyte[]metadataValue="My first namespace".getBytes(StandardCharsets.UTF_8);// Create the embedded metadata transactionfinalEmbeddedTransactionembeddedTransaction=facade.createEmbeddedTransactionFromTypedDescriptor(newNamespaceMetadataTransactionV1Descriptor(signerAddress,scopedMetadataKey,newNamespaceId(namespaceId),// When creating new metadata, valueSizeDelta// equals value lengthmetadataValue.length,metadataValue),signerKeyPair.getPublicKey());System.out.println("Created embedded metadata transaction:");System.out.println(JSON_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(embeddedTransaction.toJson()));// Build the aggregate transactionfinalList<EmbeddedTransaction>embeddedTransactions=List.of(embeddedTransaction);finalTransactiontransaction=facade.createTransactionFromTypedDescriptor(newAggregateCompleteTransactionV3Descriptor(SymbolFacade.hashEmbeddedTransactions(embeddedTransactions),embeddedTransactions,null),signerKeyPair.getPublicKey(),feeMultiplier,2*60*60);// Sign and generate final payloadfinalCryptoTypes.Signaturesignature=facade.signTransaction(signerKeyPair,transaction);StringjsonPayload=SymbolTransactionFactory.attachSignature(transaction,signature);// Announce and wait for confirmationfinalStringtransactionHash=facade.hashTransaction(transaction).toString();System.out.printf("Built aggregate transaction with hash: %s%n",transactionHash);announceTransaction(jsonPayload,"aggregate transaction");waitForConfirmation(transactionHash,"aggregate transaction");// --- MODIFYING EXISTING METADATA ---System.out.println("\n--- Modifying existing metadata ---");// Fetch current metadata value from networkfinalStringscopedKeyHex="%016X".formatted(scopedMetadataKey);finalStringnamespaceIdHex="%016X".formatted(namespaceId);finalStringmetadataPath="/metadata"+"?sourceAddress="+signerAddress+"&targetAddress="+signerAddress+"&scopedMetadataKey="+scopedKeyHex+"&targetId="+namespaceIdHex+"&metadataType=2";System.out.printf("Fetching current metadata from %s%n",metadataPath);finalJsonNodemetadataJson=getJson(metadataPath);// Get the metadata entryif(metadataJson.get("data").isEmpty())thrownewIOException("Metadata entry not found");finalJsonNodemetadataEntry=metadataJson.get("data").get(0).get("metadataEntry");finalbyte[]currentValue=java.util.HexFormat.of().parseHex(metadataEntry.get("value").asText());System.out.printf(" Current value: %s%n",newString(currentValue,StandardCharsets.UTF_8));// XOR the current and new valuesfinalbyte[]newValue="Updated namespace".getBytes(StandardCharsets.UTF_8);finalbyte[]updateValue=Metadata.updateValue(currentValue,newValue);// Create the update transaction with XOR'd valuefinalEmbeddedTransactionembeddedUpdate=facade.createEmbeddedTransactionFromTypedDescriptor(newNamespaceMetadataTransactionV1Descriptor(signerAddress,scopedMetadataKey,newNamespaceId(namespaceId),// valueSizeDelta is the difference in length// (can be negative)newValue.length-currentValue.length,updateValue),signerKeyPair.getPublicKey());System.out.println("Created embedded update transaction:");System.out.println(JSON_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(embeddedUpdate.toJson()));// Build the aggregate for the updatefinalList<EmbeddedTransaction>updateEmbedded=List.of(embeddedUpdate);finalTransactionupdateTransaction=facade.createTransactionFromTypedDescriptor(newAggregateCompleteTransactionV3Descriptor(SymbolFacade.hashEmbeddedTransactions(updateEmbedded),updateEmbedded,null),signerKeyPair.getPublicKey(),feeMultiplier,2*60*60);// Sign and announce the updatefinalCryptoTypes.SignatureupdateSignature=facade.signTransaction(signerKeyPair,updateTransaction);jsonPayload=SymbolTransactionFactory.attachSignature(updateTransaction,updateSignature);// Announce and wait for confirmationfinalStringupdateHash=facade.hashTransaction(updateTransaction).toString();System.out.printf("Built aggregate transaction with hash: %s%n",updateHash);announceTransaction(jsonPayload,"aggregate transaction");waitForConfirmation(updateHash,"aggregate transaction");}privateJsonNodegetJson(finalStringpath)throwsIOException,InterruptedException{finalHttpRequestrequest=HttpRequest.newBuilder(URI.create(nodeUrl+path)).GET().build();finalHttpResponse<String>response=HTTP_CLIENT.send(request,BodyHandlers.ofString());returnJSON_MAPPER.readTree(response.body());}}
SIGNER_PRIVATE_KEY=os.getenv('SIGNER_PRIVATE_KEY','0000000000000000000000000000000000000000000000000000000000000000')signer_key_pair=SymbolFacade.KeyPair(PrivateKey(SIGNER_PRIVATE_KEY))facade=SymbolFacade('testnet')signer_address=facade.network.public_key_to_address(signer_key_pair.public_key)print(f'Signer address: {signer_address}')# Get namespace name from environment or use defaultNAMESPACE_NAME=os.getenv('NAMESPACE_NAME','testnamespace')namespace_id=generate_namespace_id(NAMESPACE_NAME)print(f'Namespace name: {NAMESPACE_NAME}')print(f'Namespace ID: {namespace_id} (0x{namespace_id:016X})')
constSIGNER_PRIVATE_KEY=process.env.SIGNER_PRIVATE_KEY||('0000000000000000000000000000000000000000000000000000000000000000');constsignerKeyPair=newSymbolFacade.KeyPair(newPrivateKey(SIGNER_PRIVATE_KEY));constfacade=newSymbolFacade('testnet');constsignerAddress=facade.network.publicKeyToAddress(signerKeyPair.publicKey);console.log('Signer address:',signerAddress.toString());// Get namespace name from environment or use defaultconstNAMESPACE_NAME=process.env.NAMESPACE_NAME||'testnamespace';constnamespaceId=generateNamespaceId(NAMESPACE_NAME);constnamespaceIdHex=namespaceId.toString(16).toUpperCase().padStart(16,'0');console.log('Namespace name:',NAMESPACE_NAME);console.log('Namespace ID:',namespaceId.toString(),`(0x${namespaceIdHex})`);
finalStringsignerPrivateKey=System.getenv().getOrDefault("SIGNER_PRIVATE_KEY","0".repeat(64));finalKeyPairsignerKeyPair=newKeyPair(newCryptoTypes.PrivateKey(signerPrivateKey));finalAddresssignerAddress=facade.network.publicKeyToAddress(signerKeyPair.getPublicKey());System.out.printf("Signer address: %s%n",signerAddress);// Get namespace name from environment or use defaultfinalStringnamespaceName=System.getenv().getOrDefault("NAMESPACE_NAME","testnamespace");finallongnamespaceId=IdGenerator.generateNamespaceId(namespaceName);System.out.printf("Namespace name: %s%n",namespaceName);System.out.printf("Namespace ID: %s (0x%016X)%n",Long.toUnsignedString(namespaceId),namespaceId);
# Define metadata key and valuekey_string=f'description_{int(time.time())}'scoped_metadata_key=metadata_generate_key(key_string)metadata_value='My first namespace'.encode('utf8')
// Define metadata key and valueconstkeyString=`description_${Date.now()}`;constscopedMetadataKey=metadataGenerateKey(keyString);constmetadataValue=newTextEncoder().encode('My first namespace');
// Define metadata key and valuefinalStringkeyString="description_"+System.currentTimeMillis();finallongscopedMetadataKey=Metadata.generateKey(keyString);finalbyte[]metadataValue="My first namespace".getBytes(StandardCharsets.UTF_8);
# Create the embedded metadata transactionembedded_transaction=(facade.create_embedded_transaction_from_descriptor({'type':'namespace_metadata_transaction_v1','target_address':signer_address,'target_namespace_id':namespace_id,'scoped_metadata_key':scoped_metadata_key,# When creating new metadata, value_size_delta# equals the value length'value_size_delta':len(metadata_value),'value':metadata_value},signer_key_pair.public_key))print('Created embedded metadata transaction:')print(json.dumps(embedded_transaction.to_json(),indent=2))
// Create the embedded metadata transactionconstembeddedTransaction=facade.createEmbeddedTransactionFromTypedDescriptor(newdescriptors.NamespaceMetadataTransactionV1Descriptor(signerAddress,scopedMetadataKey,// When creating new metadata, valueSizeDelta// equals value lengthnewmodels.NamespaceId(namespaceId),metadataValue.length,metadataValue),signerKeyPair.publicKey);console.log('Created embedded metadata transaction:');console.log(JSON.stringify(embeddedTransaction.toJson(),null,2));
// Create the embedded metadata transactionfinalEmbeddedTransactionembeddedTransaction=facade.createEmbeddedTransactionFromTypedDescriptor(newNamespaceMetadataTransactionV1Descriptor(signerAddress,scopedMetadataKey,newNamespaceId(namespaceId),// When creating new metadata, valueSizeDelta// equals value lengthmetadataValue.length,metadataValue),signerKeyPair.getPublicKey());System.out.println("Created embedded metadata transaction:");System.out.println(JSON_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(embeddedTransaction.toJson()));
# Build the aggregate transactionembedded_transactions=[embedded_transaction]transaction=facade.create_transaction_from_descriptor({'type':'aggregate_complete_transaction_v3','transactions_hash':facade.hash_embedded_transactions(embedded_transactions),'transactions':embedded_transactions},signer_key_pair.public_key,fee_multiplier,2*60*60)
// Build the aggregate transactionconstembeddedTransactions=[embeddedTransaction];consttransaction=facade.createTransactionFromTypedDescriptor(newdescriptors.AggregateCompleteTransactionV3Descriptor(facade.static.hashEmbeddedTransactions(embeddedTransactions),embeddedTransactions,undefined),signerKeyPair.publicKey,feeMultiplier,2*60*60);
// Build the aggregate transactionfinalList<EmbeddedTransaction>embeddedTransactions=List.of(embeddedTransaction);finalTransactiontransaction=facade.createTransactionFromTypedDescriptor(newAggregateCompleteTransactionV3Descriptor(SymbolFacade.hashEmbeddedTransactions(embeddedTransactions),embeddedTransactions,null),signerKeyPair.getPublicKey(),feeMultiplier,2*60*60);
# Sign and generate final payloadsignature=facade.sign_transaction(signer_key_pair,transaction)json_payload=facade.transaction_factory.attach_signature(transaction,signature)# Announce and wait for confirmationtransaction_hash=facade.hash_transaction(transaction)print(f'Built aggregate transaction with hash: {transaction_hash}')announce_transaction(json_payload,'aggregate transaction')wait_for_confirmation(transaction_hash,'aggregate transaction')
// Sign and generate final payloadconstsignature=facade.signTransaction(signerKeyPair,transaction);constjsonPayload=facade.transactionFactory.static.attachSignature(transaction,signature);// Announce and wait for confirmationconsttransactionHash=facade.hashTransaction(transaction).toString();console.log('Built aggregate transaction with hash:',transactionHash);awaitannounceTransaction(jsonPayload,'aggregate transaction');awaitwaitForConfirmation(transactionHash,'aggregate transaction');
// Sign and generate final payloadfinalCryptoTypes.Signaturesignature=facade.signTransaction(signerKeyPair,transaction);StringjsonPayload=SymbolTransactionFactory.attachSignature(transaction,signature);// Announce and wait for confirmationfinalStringtransactionHash=facade.hashTransaction(transaction).toString();System.out.printf("Built aggregate transaction with hash: %s%n",transactionHash);announceTransaction(jsonPayload,"aggregate transaction");waitForConfirmation(transactionHash,"aggregate transaction");
# Fetch current metadata value from networkmetadata_path=(f'/metadata?sourceAddress={signer_address}'f'&targetAddress={signer_address}'f'&scopedMetadataKey={scoped_metadata_key:016X}'f'&targetId={namespace_id:016X}''&metadataType=2')print(f'Fetching current metadata from {metadata_path}')withurllib.request.urlopen(f'{NODE_URL}{metadata_path}')asresponse:response_json=json.loads(response.read().decode())# Get the metadata entryifnotresponse_json['data']:raiseRuntimeError('Metadata entry not found')metadata_entry=response_json['data'][0]['metadataEntry']current_value=bytes.fromhex(metadata_entry['value'])print(f' Current value: {current_value.decode("utf8")}')
// Fetch current metadata value from networkconstscopedKeyHex=scopedMetadataKey.toString(16).toUpperCase().padStart(16,'0');constmetadataPath='/metadata'+`?sourceAddress=${signerAddress}`+`&targetAddress=${signerAddress}`+`&scopedMetadataKey=${scopedKeyHex}`+`&targetId=${namespaceIdHex}`+'&metadataType=2';console.log('Fetching current metadata from',metadataPath);constmetadataResponse=awaitfetch(`${NODE_URL}${metadataPath}`);constmetadataJSON=awaitmetadataResponse.json();// Get the metadata entryif(!metadataJSON.data.length)thrownewError('Metadata entry not found');constmetadataEntry=metadataJSON.data[0].metadataEntry;constcurrentValue=Buffer.from(metadataEntry.value,'hex');console.log(' Current value:',currentValue.toString('utf8'));
// Fetch current metadata value from networkfinalStringscopedKeyHex="%016X".formatted(scopedMetadataKey);finalStringnamespaceIdHex="%016X".formatted(namespaceId);finalStringmetadataPath="/metadata"+"?sourceAddress="+signerAddress+"&targetAddress="+signerAddress+"&scopedMetadataKey="+scopedKeyHex+"&targetId="+namespaceIdHex+"&metadataType=2";System.out.printf("Fetching current metadata from %s%n",metadataPath);finalJsonNodemetadataJson=getJson(metadataPath);// Get the metadata entryif(metadataJson.get("data").isEmpty())thrownewIOException("Metadata entry not found");finalJsonNodemetadataEntry=metadataJson.get("data").get(0).get("metadataEntry");finalbyte[]currentValue=java.util.HexFormat.of().parseHex(metadataEntry.get("value").asText());System.out.printf(" Current value: %s%n",newString(currentValue,StandardCharsets.UTF_8));
# XOR the current and new valuesnew_value='Updated namespace'.encode('utf8')update_value=metadata_update_value(current_value,new_value)# Create the update transaction with XOR'd valueembedded_update=facade.create_embedded_transaction_from_descriptor({'type':'namespace_metadata_transaction_v1','target_address':signer_address,'target_namespace_id':namespace_id,'scoped_metadata_key':scoped_metadata_key,# value_size_delta is the difference in length# (can be negative)'value_size_delta':len(new_value)-len(current_value),'value':update_value},signer_key_pair.public_key)print('Created embedded update transaction:')print(json.dumps(embedded_update.to_json(),indent=2))
// XOR the current and new valuesconstnewValue=newTextEncoder().encode('Updated namespace');constupdateValue=metadataUpdateValue(currentValue,newValue);// Create the update transaction with XOR'd valueconstembeddedUpdate=facade.createEmbeddedTransactionFromTypedDescriptor(newdescriptors.NamespaceMetadataTransactionV1Descriptor(signerAddress,scopedMetadataKey,newmodels.NamespaceId(namespaceId),// valueSizeDelta is the difference in length// (can be negative)newValue.length-currentValue.length,updateValue),signerKeyPair.publicKey);console.log('Created embedded update transaction:');console.log(JSON.stringify(embeddedUpdate.toJson(),null,2));
// XOR the current and new valuesfinalbyte[]newValue="Updated namespace".getBytes(StandardCharsets.UTF_8);finalbyte[]updateValue=Metadata.updateValue(currentValue,newValue);// Create the update transaction with XOR'd valuefinalEmbeddedTransactionembeddedUpdate=facade.createEmbeddedTransactionFromTypedDescriptor(newNamespaceMetadataTransactionV1Descriptor(signerAddress,scopedMetadataKey,newNamespaceId(namespaceId),// valueSizeDelta is the difference in length// (can be negative)newValue.length-currentValue.length,updateValue),signerKeyPair.getPublicKey());System.out.println("Created embedded update transaction:");System.out.println(JSON_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(embeddedUpdate.toJson()));
既存のメタデータエントリを更新するには、前述のようにネットワークから取得した現在の値が必要です。
メタデータの更新を実演するために、コードは同じスコープ指定メタデータキーを使用して別の NamespaceMetadataTransactionV1 トランザクションを作成し、説明を My first namespace から Updated namespace に変更します。
# Build the aggregate for the updateembedded_transactions=[embedded_update]update_transaction=facade.create_transaction_from_descriptor({'type':'aggregate_complete_transaction_v3','transactions_hash':facade.hash_embedded_transactions(embedded_transactions),'transactions':embedded_transactions},signer_key_pair.public_key,fee_multiplier,2*60*60)# Sign and announce the updatesignature=facade.sign_transaction(signer_key_pair,update_transaction)json_payload=facade.transaction_factory.attach_signature(update_transaction,signature)# Announce and wait for confirmationupdate_hash=facade.hash_transaction(update_transaction)print(f'Built aggregate transaction with hash: {update_hash}')announce_transaction(json_payload,'aggregate transaction')wait_for_confirmation(update_hash,'aggregate transaction')
// Build the aggregate for the updateconstupdateEmbedded=[embeddedUpdate];constupdateTransaction=facade.createTransactionFromTypedDescriptor(newdescriptors.AggregateCompleteTransactionV3Descriptor(facade.static.hashEmbeddedTransactions(updateEmbedded),updateEmbedded,undefined),signerKeyPair.publicKey,feeMultiplier,2*60*60);// Sign and announce the updateconstupdateSignature=facade.signTransaction(signerKeyPair,updateTransaction);constupdatePayload=facade.transactionFactory.static.attachSignature(updateTransaction,updateSignature);// Announce and wait for confirmationconstupdateHash=facade.hashTransaction(updateTransaction).toString();console.log('Built aggregate transaction with hash:',updateHash);awaitannounceTransaction(updatePayload,'aggregate transaction');awaitwaitForConfirmation(updateHash,'aggregate transaction');
// Build the aggregate for the updatefinalList<EmbeddedTransaction>updateEmbedded=List.of(embeddedUpdate);finalTransactionupdateTransaction=facade.createTransactionFromTypedDescriptor(newAggregateCompleteTransactionV3Descriptor(SymbolFacade.hashEmbeddedTransactions(updateEmbedded),updateEmbedded,null),signerKeyPair.getPublicKey(),feeMultiplier,2*60*60);// Sign and announce the updatefinalCryptoTypes.SignatureupdateSignature=facade.signTransaction(signerKeyPair,updateTransaction);jsonPayload=SymbolTransactionFactory.attachSignature(updateTransaction,updateSignature);// Announce and wait for confirmationfinalStringupdateHash=facade.hashTransaction(updateTransaction).toString();System.out.printf("Built aggregate transaction with hash: %s%n",updateHash);announceTransaction(jsonPayload,"aggregate transaction");waitForConfirmation(updateHash,"aggregate transaction");