[NEM] sdkでapostilleを実装する

var nem = require("nem-sdk").default;

const password = '';
const privateKey = '';
const common = nem.model.objects.create('common')(password, privateKey);
const fileName = "sample.txt";
const content = "Apostille is awesome !";
const tag = "Test Apostille";
var fileContent = nem.crypto.js.enc.Utf8.parse(content);

var endpoint = nem.model.objects.create("endpoint")(nem.model.nodes.defaultMainnet, nem.model.nodes.defaultPort);

var apostille = nem.model.apostille.create(common, "Test.txt", fileContent, tag, nem.model.apostille.hashing["SHA256"], false, {}, true, nem.model.network.data.mainnet.id);



async function main() {
	nem.model.transactions.send(common, apostille.transaction, endpoint).then(function(res){
		// If code >= 2, it's an error
		if (res.code >= 2) {
			console.error(res.message);
		} else {
			console.log("\nTransaction: " + res.message);
			console.log("\nCreate a file with the fileContent text and name it:\n" + apostille.data.file.name.replace(/\.[^/.]+$/, "") + " -- Apostille TX " + res.transactionHash.data + " -- Date DD/MM/YYYY" + "." + apostille.data.file.name.split('.').pop());
			console.log("When transaction is confirmed the file should audit successfully in Nano");
			console.log("\nYou can also take the following hash: " + res.transactionHash.data + " and put it into the audit.js example");
		}
	}, function(err) {
		console.error(err);
	});
}

main();

$ node apostille.js

Transaction: SUCCESS

Create a file with the fileContent text and name it:
Test — Apostille TX 22817314fc9e51742ce6a5836e1ad7bb622cf32289d546831d1ab99224618c2f — Date DD/MM/YYYY.txt
When transaction is confirmed the file should audit successfully in Nano

You can also take the following hash: 22817314fc9e51742ce6a5836e1ad7bb622cf32289d546831d1ab99224618c2f and put it into the audit.js example

おおおおおお、完全に理解した。

### apostilleのcheck

var nem = require("nem-sdk").default;

const content = "Apostille is awesome !";
var fileContent = nem.crypto.js.enc.Utf8.parse(content);

var endpoint = nem.model.objects.create("endpoint")(nem.model.nodes.defaultMainnet, nem.model.nodes.defaultPort);

var txHash = "22817314fc9e51742ce6a5836e1ad7bb622cf32289d546831d1ab99224618c2f"


async function main() {
	nem.com.requests.transaction.byHash(endpoint, txHash).then(function(res) {
	  // Verify
	  if (nem.model.apostille.verify(fileContent, res.transaction)) {
	    console.log("Apostille is valid");
	  } else {
	    console.log("Apostille is invalid");
	  }
	}, function(err) {
	  console.log("Apostille is invalid");
	  console.log(err);
	});
}

main();

$ node confirm.js
Apostille is valid

すげええええええええ
これを実装する

よっしゃあああああああああああああああああああああああ
あとはNEMの価格を取得して表示するのみ

[NEM] Apostilleで実装したい

public apostilleとprivate apostilleがある

## open apostille
https://www.openapostille.net/detail/797ae3b488f7808bf3b7ad46c7f487f2b02645175f09256ca532eb74b274d319

Txhash: 797ae3b488f7808bf3b7ad46c7f487f2b02645175f09256ca532eb74b274d319
ファイル名: ジャパンカップ予想 — Apostille TX 797ae3b488f7808bf3b7ad46c7f487f2b02645175f09256ca532eb74b274d319 — Date 2017-11-25.docx

## transfer transaction:
http://chain.nem.ninja/#/transfer/797ae3b488f7808bf3b7ad46c7f487f2b02645175f09256ca532eb74b274d319

Message: 4e545903560fc41a6f8c9495ee7e7e18322973c50e9e2f4fbb91fa892343412586d9a808

### public apostilleの詳細
fe4e545903560fc41a6f8c9495ee7e7e18322973c50e9e2f4fbb91fa892343412586d9a808

fe 16進数
4e5459 apostilleを示す
0 public(privateは9)
3 hash algorithm sha256(1:md5, 2:sha1, 3:sha256, 8:sha3-256, 9:sha3-512などがある)
560fc41a6f8c9495ee7e7e18322973c50e9e2f4fbb91fa892343412586d9a808 hash

$ sha256sum “ジャパンカップ予想 — Apostille TX 797ae3b488f7808bf3b7ad46c7f487f2b02645175f09256ca532eb74b274d319 — Date 2017-11-25.docx”
560fc41a6f8c9495ee7e7e18322973c50e9e2f4fbb91fa892343412586d9a808 ジャパンカップ予想 — Apostille TX 797ae3b488f7808bf3b7ad46c7f487f2b02645175f09256ca532eb74b274d319 — Date 2017-11-25.docx

一致する
sha256sumコマンドはSHA-256を用いて、256ビット(64桁の16進数)を出力

NanoWalletではファイル名の記載されたトランザクションハッシュからハッシュ値が記録されたメッセージを取得し、
メッセージから取り出したハッシュ値とファイルのハッシュ値を付き合わせて完全性を証明している
存在証明はそのトランザクションのタイムスタンプを利用する
-> 上記の2つで、ある時点でこのファイルが存在していたと証明できる
アポスティーユはトランザクションの応用

#### NanoWalletで作成してみる

{"data":[
{"filename":"test.txt",
 "tags":"test",
  "fileHash":"fe4e545983efc827e551fcd0c8429a468a7c6c64f5f231b1221c3ecffdbfff00dacdd9a95aed46a4d30e88cf83dfdf9a49beb4a7e748bcde7465ac15e202a50ad28f44f606",
  "owner":"NDXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "fromMultisig":"NDIWUXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "dedicatedAccount":"NCFYBGQXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "dedicatedPrivateKey":"79e4a484XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "txHash":"bea36f12fe14a046ab849f8df097fbe238aae457e45a36854d800d8f45c52b33",
  "txMultisigHash":"",
  "timeStamp":"Sat, 18 Dec 2021 14:35:34 GMT"
 }]}

filename, tag, filehash, owner, fromMultisig, dedicatedAccount, dedicatedPrivtateKey, txHash, txMultisigHash, timeStamp

MessageHEX: 4e545903 5526798746c3bdabb663b681ed78c2f8ac0b13b275dc4f95d4941fc58d7258e0

$ sha256sum “sample — Apostille TX 52d76444c713f3f84e5c44107cce511d974a250b91c5c49a1323bfe838da0f5a — Date 2021-12-19.txt”
5526798746c3bdabb663b681ed78c2f8ac0b13b275dc4f95d4941fc58d7258e0 sample — Apostille TX 52d76444c713f3f84e5c44107cce511d974a250b91c5c49a1323bfe838da0f5a — Date 2021-12-19.txt

ダウンロードしたファイルのsha256でhash計算した値が、MessageのHash値と一致していることで、このファイルが、この時間にあったことを証明している。

ンンン、なるほどー

[NEM] mosaicで商品購入ページを作りたい

基本的にはsendと同じだが、商品を選択して、商品数を入力できるようにすれば良い

		<div class="card column">
			<center><input type="radio" name="art" value="1" checked></center>
		</div>
		<div class="card column">
			<center><input type="radio" name="art" value="2"></center>
		</div>
		<div class="card column">
			<center><input type="radio" name="art" value="3"></center>
		</div>

		<div class="field" width="90%" style="margin:20px">
			<label class="label">Amount</label>
			<div class="control ">
				<input class="input" size="3" type="number" id="amount" style="width: 33%;" placeholder="" value="1">
			</div>
		</div>

js: 商品情報を連想配列で持って、radioボタンが押された時に、配列の何番目かを取得すれば良い

		var products = [
			{name:"Rime ethics", price:"20"},
			{name:"Midnight Asia", price:"30"},
			{name:"Dreams & Struggle", price:"90"},
		]

		// 省略

		function OnButtonClick() {
			let checkValue = "";
			let elements = document.getElementsByName('art');
			for (let i = 0; i < elements.length; i++){
			    if (elements.item(i).checked){
			        checkValue = i;
			    } 
			}
			sendAmountNem = parseInt(products[checkValue]['price']) * amount.value;
			name = products[checkValue]['name'];
			if (!walletpassword.value || !privatekey.value) {
			    resArea.innerHTML = "Wallet Password、privatekeyを入力してください";
			} else {
			    main();
			}		
			
		}

割とやりたいことはできたか…

[NEM] Wallet情報の取得

var nem = require("nem-sdk").default;

const endpoint = nem.model.objects.create('endpoint')(nem.model.nodes.defaultMainnet, nem.model.nodes.defaultPort);

const mainnetAddress = '****'

async function main() {
	await nem.com.requests.account.data(endpoint, mainnetAddress).then(res => {
		console.log('balance:', res.account);
	}).catch(err => {
		console.log(err);
	});
}

main();

$ node wallet.js
balance: { address: ‘****’,
harvestedBlocks: 0,
balance: 00000000,
importance: 0,
vestedBalance: 00000000,
publicKey:
‘****’,
label: null,
multisigInfo: {} }

なるほどね、アカウントにいくら入ってるかってのは誰でも見れちゃうんだな

[JavaScript] inputに入力があれbuttonを押せるようにする

btn.disabled = true; でbuttonを制御します。
input.addEventListener(“change”, func); で btn.disabledの状態を変更する

let btn = document.getElementById('btn');
		let wallet = document.getElementById('wallet');
		let message = document.getElementById('message');
		let amount = document.getElementById('amount');
		let resArea = document.getElementById("resArea");
		btn.disabled = true; 
		wallet.addEventListener("change", stateHandle);
		amount.addEventListener("change", stateHandle);
		message.addEventListener("change", stateHandle);
		function stateHandle() {
		  if (wallet.value == "" || amount.value == "") {
		    btn.disabled = true; 
		  } else {
		    btn.disabled = false;
		  }
		}

		function OnButtonClick() {
			if (!wallet.value || !message.value || !amount.value) {
			    resArea.innerHTML = "Wallet Address、amount、messageを入力してください";
			} else {
			    main();
			}		
			
		}
		async function main() {
			console.log("送金完了しました")
			console.log(wallet.value)
			console.log(message.value)
			console.log(amount.value)
			resArea.innerHTML = "送金完了しました";
		}

最初

入力後

OK
これで実際に送金できるかテストする

しゃあああああああああああああああああああ
次はxem amountの取得かな

[NEM] node.jsでmosaicを送信

nem-sdkをインストールします
$ npm install nem-sdk

mainnetで送信します。

var nem = require("nem-sdk").default;

const endpoint = nem.model.objects.create('endpoint')(nem.model.nodes.defaultMainnet, nem.model.nodes.defaultPort);

async function main() {

    const toAddress = '';
    const sendAmount = 1;
    const sendMsg = 'Hello World!';
    const password = '';
    const privateKey = '';
    const common = nem.model.objects.create('common')(password, privateKey);
    const yourMosaicNamespace = 'capitalcoin';
    const yourMosaicName = 'hpscript';

    let transferTransaction = nem.model.objects.create('transferTransaction')(toAddress, sendAmount, sendMsg);

    const xemMozaic = nem.model.objects.create('mosaicAttachment')('nem', 'xem', 0);
    transferTransaction.mosaics.push(xemMozaic);

    const yourMosaic = nem.model.objects.create('mosaicAttachment')(yourMosaicNamespace, yourMosaicName, 10);
    transferTransaction.mosaics.push(yourMosaic);

    let mosaicDefinitionMetaDataPair = nem.model.objects.get('mosaicDefinitionMetaDataPair');
    nem.com.requests.namespace.mosaicDefinitions(endpoint, yourMosaic.mosaicId.namespaceId).then(res => {

        const neededDefinition = nem.utils.helpers.searchMosaicDefinitionArray(res.data, [yourMosaicName]);

        const fullMosaicName  = nem.utils.format.mosaicIdToName(yourMosaic.mosaicId);

        if (undefined === neededDefinition[fullMosaicName]) {
            return console.log('Mosaic not found !');
        }

        mosaicDefinitionMetaDataPair[fullMosaicName] = {};
        mosaicDefinitionMetaDataPair[fullMosaicName].mosaicDefinition = neededDefinition[fullMosaicName];

        nem.com.requests.mosaic.supply(endpoint, fullMosaicName).then(supplyRes => {

            mosaicDefinitionMetaDataPair['nem:xem'].supply = 8999999999;
            mosaicDefinitionMetaDataPair[fullMosaicName].supply = supplyRes.supply;

            const transactionEntity = nem.model.transactions.prepare('mosaicTransferTransaction')(common, transferTransaction, mosaicDefinitionMetaDataPair, nem.model.network.data.mainnet.id);

            nem.model.transactions.send(common, transactionEntity, endpoint).then(sendRes => {
                console.log('sendRes:', sendRes);
            }).catch(sendErr => {
                console.log('sendError:', sendErr);
            });
        }).catch(supplyErr => {
            console.log('supplyErr:', supplyErr);
        });
    }).catch(err => {
        console.log('mosaicDefinitionsError:', err);
    });
}

main();

$ node test.js
sendRes: { innerTransactionHash: {},
code: 1,
type: 1,
message: ‘SUCCESS’,
transactionHash:
{ data:
‘f08066a73d37f523482d6dc61a60e53db4cbd5097262f1ee419cae7ae4ad9a7a’ } }

送信結果

おおお、これをUIをつけてやりたい

<body>
	<div class="container">
		<h1 class="title">NEM Project</h1>
		<p>送金ボタンを押してください</p>
		<input type="button" value="送金" onclick="OnButtonClick();">
	</div>
	<script src="nem-sdk.js"></script>
	<script>
		var nem = require("nem-sdk").default;
		
		function OnButtonClick() {
			main();
			console.log("送金完了しました")
		}
		const endpoint = nem.model.objects.create('endpoint')(nem.model.nodes.defaultMainnet, nem.model.nodes.defaultPort);
		async function main() {
		    // 省略
		}
	</script>

あ、出来た^^

受け取るwalletのアドレスとメッセージを入力フォームにして、そこに送信できるようにしたい。

[NEM] NEM Walletから独自通貨(mosaic)を送金

Nem用のwalletであるRaccoon Walletをスマホにインストールし、ウォレットのアドレスを取得します。

RaccoonWallet
https://apps.apple.com/jp/app/raccoonwallet/id1437034062

NEM WalletからRaccoon Walletのアドレスへ、mosaicを送信します

Raccoon Wallet側で受け取ったトランザクションを確認

おおおお、なんか凄い
これをプログラムでやりたい。出来ればUI付きで

[NEM/XEM] 独自トークンの発行

NEMのサイトに飛びます
https://discord.com/invite/xymcity

これはdiscordのチャットですね

Symbol
https://jp.symbolplatform.com/

Nemplatform wallet

Wallets


これか

import してログインする

namespace : 独自トークンを機能させるための場所
mosaic : トークの詳細設定(名称、初期供給量、小数点)

早速NEM Walletにnemを送ってみます。120NEMが必要ということなので、124NEM送る
NEMはBlock chainに比べて、blockが作られる時間が早い
https://explorer.nemtool.com/

すると、アカウントに124NEMが入っている!

### namespace
create namespaceでcapitalcoinとします
すると、100.15NEM引かれて、Dashboardでnamespaceが作られます

### Mosaics
namespaceが作られると、mosaicsの作成ができるようになります。
Mosaic name: hpscript
Description: Hpscript
Initial Supply: 100000000
Total Supply: 100000000

### Mosaicの送信
もにゃに送信できるらしいが、もにゃ側でエラーになる…

発行は簡単にできるが、使い方がイマイチやな