SSS(Safely Sign Symbol) ExtensionでSymbolブロックチェーンの送金を体験する。

今日はChrome拡張機能として公開されたSSS(Safely Sign Symbol) Extensionを使ったSymbolブロックチェーンの送金を体験してみます。

SSSは @inatatsu_csg さんによって開発されたSymbolブロックチェーン上で安全に署名を行うための拡張機能です。詳細は以下リンクをご参照ください。
 
https://github.com/inatatsu-tatsuhiro/SSS-Extension

http://sss.inatatsu.com/

後記：こちらの記事もご参考ください。

https://zenn.dev/inatatsu/articles/51c1d8de76d335

https://qiita.com/gnapha/items/1ba3ed0eb89f3a079098



# インストール確認

chromeブラウザで任意のページへアクセスして（適当なノードのURLをお勧めします）、F12キーで開発者コンソールを開き、以下の一行を打ち込みます。


```js
window.SSS

//このように出力されればインストール済みです。
>{isSet: false, signedFrag: false, signedTx: null, activePublicKey: '****', setTransaction: ƒ, …}
```

##### 注意！最新バージョンのSSSでは使用するページの連携が必要になりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/561fcae2-210b-c1ca-e9c5-6c5ba0d5139c.png)

SSSを使いたいページで右クリックしてSSSと連携する、をクリックしてください。
**次回ページ表示時**からSSSと連携できるようになります。


##### インストールされていない場合

インストールされていない場合はこちらからインストールを行います。

https://chrome.google.com/webstore/detail/sss-extension/llildiojemakefgnhhkmiiffonembcan

ブラウザの右上パズルピースをクリックしてSSS Extensionを選択し、アカウントを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/565f989a-24ef-6ff0-5ace-1636a02bc1be.png)

右上のADD ACCOUNTを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/d2e2a246-a985-e879-1488-cef37dd6a607.png)

アカウント登録ではアドレスと秘密鍵を入力します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/7dc425ce-b088-1056-92f0-fbdd5ee81fa9.png)

アドレスを入力するのは、メインネットかテストネットかを判断するためと思われます。登録が成功すると自動的にどちらのネットワークを使うか判定されます。

※開発者さんから補足がありました

> ネットワークの判別の意図もありますが、なぜネットワークをラジオボタンで選択等の方法を取っていないかというと、秘密鍵をコピペする際のミス(1文字目がコピーできてないかつペースト時に「v」が入ってしまう場合等)を機械的に判別できるように秘密鍵から導出されるアドレスと入力したアドレスが一致しているかを確認しています～


:::note alert
秘密鍵を入力するため使用は自己責任でお願いします。
最初はまず、テストネットで大きな額の入っていない少量のアカウントでお試しください。
:::


# 送金体験

ここからは以下の記事を参考に書いていきます。
まだ試したことの無い方はこちらを先にご体験ください。

https://qiita.com/nem_takanobu/items/e2b1f0aafe7a2df0fe1b

### 設定値の定義とライブラリのインポート

```js
NODE = window.origin;
GENERATION_HASH = '7FCCD304802016BEBBCD342A332F91FF1F3BB5E902988B352697BE245F48E836';
EPOCH_ADJUSTMENT = 1637848847;

(script = document.createElement('script')).src = 'https://xembook.github.io/nem2-browserify/symbol-sdk-1.0.3.js';
document.getElementsByTagName('head')[0].appendChild(script);

```
### ライブラリのインスタンス生成

```js
sym = require("/node_modules/symbol-sdk");
```

### 送信用アカウントの作成と準備

必要ありません！
(SSSに登録したアカウントに残高がない場合はFaucetで補充しておいてください)

### トランザクション作成

```js
tx = sym.TransferTransaction.create(
    sym.Deadline.create(EPOCH_ADJUSTMENT),
    sym.Address.createFromRawAddress("TDMYLKCTEVPSRPTG4UXW47IQPCYNLW2OVWZMLGY"), 
    [new sym.Mosaic (new sym.MosaicId('3A8416DB2D53B6C8'),sym.UInt64.fromUint(1000000))],
    sym.PlainMessage.create('Hello Symbol'),
    sym.NetworkType.TEST_NET,
    sym.UInt64.fromUint(100000)
);
```

### 署名

コンソール上で署名を行わず、SSS上で署名します。

```js

window.SSS.setTransaction(tx)
signedTx = await window.SSS.requestSign();
```

これでコンソールは待機中になりました。
もう一度右上のSSSを開くとトランザクションの内容が列記されているので、SGINボタンで署名します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/806cb1c6-73d9-d457-b39d-9194401414aa.png)

待機中だったコンソールに署名済みトランザクションが出力されます。

```js
{payload: 'BD000000000000007FBE1CA0DEBEE621824A3985107F4309B6…B16843A40420F00000000000048656C6C6F2053796D626F6C', hash: '37560A4412CCCC0FE1A12A66964AF3D2A94E488044A72EF5294919895E5C42CD', signerPublicKey: 'CF4D04AC315DE72091D02ADCA828DA14F0311F8C1E4CF383E21E6A7A3AE23811', type: 16724, networkType: 152}
```

### 署名したトランザクションをネットワークにアナウンス

署名済みトランザクションを入手できたのでネットワークにアナウンスしましょう。

```js
new sym.TransactionHttp(NODE)
    .announce(signedTx)
    .subscribe((x) => console.log(x), (err) => console.error(err));
```

アナウンス後の確認方法は今までと同様です。無事送金できたかご確認ください。

# 連署
ver 1.0.2 になり、アグリゲート・ボンデッドトランザクションの連署が出来るようになりました。
他のサービス提供者が発行したトランザクションを承認する形でSSSが利用できます。

###### 署名待ち中のパーシャルトランザクションをハッシュ値で検索
```js
aggTx = await new sym.TransactionHttp(NODE)
.getTransaction(hash,sym.TransactionGroup.Partial).toPromise();
```

###### SSSにトランザクションをセット、連署を要求
```js
window.SSS.setTransaction(aggTx );
signedCosTx = await window.SSS.requestSignCosignatureTransaction();
```

###### 連署済みトランザクションをアナウンス
```js
await new sym.TransactionHttp(NODE)
.announceAggregateBondedCosignature(signedTx).toPromise();
```


# さいごに

いかがでしたでしょうか？
コンソールで記述したスクリプトがユーザの秘密鍵に触れることなく、ブロックチェーンでの送金が実現しましたね。
これが意味することは、SSSを活用したアプリケーションにおいては、SSSのセキュリティさえ検証していればアプリの署名に関わるセキュリティを検証する必要がない、ということです。
送金だけではなくログインに使うこともできそうですね。

SSSは今後ハードウェアウォレットでの署名にも対応するようなので、そのあたりの更新があればまた使い勝手をレポートさせていただきます。