ブロックチェーンを利用した存在証明についてご紹介します。
今回はSymbolを使用して、約80行ほどのJavaScriptでファイルのハッシュ値をブロックチェーンに記録してみます。
存在証明とは
データの要約値となるハッシュ値をブロックチェーンに記録することで、そのデータを取り込んだブロックのタイムスタンプ
、そのデータを記録した署名者
の情報が改竄されずに後から検証可能な状態にできます。データ全体を保存するのではなく要約値のみ保存するのでプライバシー情報がブロックチェーンに記録されることはありません。
今回使用するスクリプトは秘密鍵を直接使用します。
テストネットなどで使用するか、あるいは1XYMなど少額の手数料費しか持ち合わせていないアカウントでご利用ください。
必要なもの
- 秘密鍵
- ブラウザ(ネット環境)
- 0.0225XYM(現在約0.1円)
ノード選択
以下のノード一覧から同期しているブロック高に注意してエンドポイントを選択してください。
(Height列の httpのリンクをクリック)
mainnet
testnet
スクリプト
ブラウザでノードのURLをクリックしたらF12キーを押して開発者コンソールを開き、以下のスクリプトをコピーペーストします。
PRIVATE_KEYには各自1XYM程度を事前に送信しておいたアカウントの秘密鍵を指定してください。
const PRIVATE_KEY = "{ここに秘密鍵を入力}";
const node = window.origin;
const res = await fetch(node + "/network/properties");
const json = await res.json();
const networkId = json.network.identifier;
const epochAdjustment = Number(json.network.epochAdjustment.replace("s",""));
const bundle = await import("https://www.unpkg.com/symbol-sdk@3.2.3/dist/bundle.web.js");
const core = bundle.core;
const sym = bundle.symbol;
const chain = new sym.SymbolFacade(networkId);
async function sha256(data) {
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}
function clog(signedHash){
console.log(node + "/transactionStatus/" + signedHash);
console.log(node + "/transactions/confirmed/" + signedHash);
if(networkId === "mainnet"){
console.log("https://symbol.fyi/transactions/" + signedHash);
}else{
console.log("https://testnet.symbol.fyi/transactions/" + signedHash);
}
}
function setMaxFee(tx,multiplier){
return new sym.models.Amount(BigInt(tx.size * multiplier))
}
function createDeadline(secs = 7200) {
const value = ((Math.trunc(Date.now() / 1000) + secs) - epochAdjustment) * 1000
return BigInt(value);
}
const prikey = new core.PrivateKey(PRIVATE_KEY)
const kpair = new sym.KeyPair(prikey);
const pubkey = kpair.publicKey;
const address = chain.network.publicKeyToAddress(kpair.publicKey);
const input = document.createElement('input');
input.type = 'file';
input.addEventListener('change', (event) => {
const file = event.target.files[0]; // 選択された最初のファイル
const reader = new FileReader();
reader.onload = async (event) => {
const arrayBuffer = event.target.result;
const apos = await sha256(arrayBuffer)
const messageData = new Uint8Array([
0x00,
...new TextEncoder().encode(apos),
]);
const tx = chain.transactionFactory.create({
type: 'transfer_transaction_v1',
signerPublicKey: pubkey,
deadline:createDeadline(),
recipientAddress: address,
message:messageData,
});
tx.fee = setMaxFee(tx,100);
const signature = chain.signTransaction(kpair,tx);
const requestBody = sym.SymbolTransactionFactory.attachSignature(tx, signature);
const res = await fetch(
new URL('/transactions', node),
{
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: requestBody,
}
);
clog(chain.hashTransaction(tx).toString());
};
reader.readAsArrayBuffer(file);
});
input.click();
存在証明実行
スクリプトを実行すると、ファイル選択ダイアログが表示されるので存在証明したいファイルを選択します。
リンクが3つ表示されるので、一番下のエクスプローラーのリンクをクリックしてブロックチェーンに記録されたことを確認してください。
検証
OSのファイルハッシュ値を出力するコマンドで、ハッシュ値が正しいかどうかを確認します。
Windows
certutil -hashfile {ファイル名} SHA256
Mac
shasum -a 256 {ファイル名}
Linux
sha256sum {ファイル名}