Hashed Time-Locked Contract を試す

# 概要

Hashed Time-Locked Contract については、以下のページで解説している。

https://qiita.com/noumia/items/f4cc59f8cf5e6084d53b

Litecoin (testnet) を使用して、実際にこの取引を試してみよう。

tenstnet の coin は、財産的価値を持たないため、Faucet サイト等でお試し用に少量の coin を配布している。
このようなサイトを利用すれば、特に自分でウォレットを用意する必要はない。その場合、試した coin を返還するアドレスがサイトに記載されているので、受け取り用アドレスにはそのアドレスを指定する。

試行環境は、Windows 10 である。

以下で、curl コマンドを使用しているが、Windows 10 April 2018 Update (1803) には標準添付されている。


# 鍵ツールのダウンロード

取引に使用する鍵を作成するためのツールをダウンロードする。

https://github.com/noumia/key-forge/releases/download/1.2/key-forge.exe


https://github.com/noumia/key-forge
https://hub.docker.com/r/noumia/key-forge/

このツールは、透明性確保のため、Golang によるオープンソースプログラムであり、再現性のあるビルドを docker (dockerhub) で提供している。
Windows と Linux (ともに x64) のバイナリーを準備しているが、ご自身でビルドしても構わない。


# Alice の準備

出金用のキーペアを以下のコマンドで作成して、PubkeyHash を Bob へ伝える。

```
> key-forge -t tltc
```

# Bob の準備

払い戻し用のキーペアを以下のコマンドで作成する。

```
> key-forge -t tltc
```

出金用のロックシークレット (Secret) とハッシュ (Hash) を以下のコマンドで作成する。

```
> key-forge -s
```

以下のサイトで、HTLC スクリプトを作成する。

https://nora.noumia.net/htlc

Tikcer には、tLTC (Litecoin testnet) を選択する。

出金 公開鍵ハッシュに、Alice から受け取った PubkeyHash を設定する。

出金 ロックハッシュに、作成した Hash を設定する。

払い戻し 公開鍵ハッシュに、自分の PubkeyHash を設定する。

払い戻し制限日時に、双方で同意した日時を設定する。

作成ボタンをクリックすると、HTLC スクリプト用のページが開くので、URL を控える。

スクリプト用ページ URL は、Permalink となっているので、Alice とリンクを共有する。


# 取引の手続き

Alice は、受け取った URL を開き、スクリプトの内容をレビューする。チェックする内容は、出金 公開鍵ハッシュが、自分の PubkeyHash になっているかと、払い戻し 制限日時が、双方合意した日時になっているかの２点となる。

Alice が、スクリプトに問題ないと確認出来たら、Bob は、入金アドレス (scriptHash) へ、所定の coin を入金する。

入金後は、トランザクション問い合わせボタンをクリックして、入金額を確認できる。確認数が、十分な数 (6 - 10 以上) に達したら、入金が確定するので、出金準備を行う。


## 出金の手続き

Alice が、取引に合意したら、商品と引き換えに Bob は、作成した Secret を Alice へ提供する。

Alice は、出金準備ボタンをクリックして、以下の項目を入力する。

* 出金アドレスに、自分の受け取り用ウォレットアドレス
* Secret に、Bob から受け取った Secret
* Donation は、サイト側への寄付額 (testnet は 0% でもよい)
* トランザクション手数料は、出金トランザクションの手数料 (デフォルト値でもよい)

作成ボタンをクリックすると、トランザクション作成用ページが開く。

この段階では手続きは完了しておらず、実際に coin の受け取りを行うには、以下の処理を行う必要がある。

1. トランザクションひな型の取得
2. トランザクションへの署名
3. 署名済みトランザクションを Blockchain P2P ネットワークへブロードキャスト

これらの処理は、以下のコマンドを実行するとで完了する。

```
> curl -s {トランザクション作成用ページから取得した Link の URL} | ^
key-forge -j -k {取引用に作成した (Alice の) PrivateKey} | ^
curl -X POST -d @- -H "content-type: application/json" https://testnet.litecore.io/api/tx/send
```

上記のコマンドの各行は、上記手続きに対応している。

トランザクションが承認されれば、受け取り用ウオレットアドレスに入金が行われる。

これらの手続きは、払い戻し制限日時前に完了させる必要がある。

### この取引の例

https://nora.noumia.net/htlc/tltc/QXHZ7Q39q9gfw1aqeVjhKLYvyuE7d67JV4

ブロックチェーン上に Secret が記録されることに注意。(Secret は使いまわせない)


## 払い戻し準備

Alice が、最終的な取引に合意したかった場合、Bob は、資金を引き揚げるための払い戻しを行う。

Bob は、払い戻し準備ボタンをクリックして、以下の項目を入力する。

* 出金アドレスに、自分の受け取り用ウォレットアドレス
* トランザクション手数料は、出金トランザクションの手数料 (デフォルト値でもよい)

作成ボタンをクリックすると、トランザクション作成用ページが開く。

出金時と同様にこの段階では手続きは完了しておらず、実際に coin の受け取りを行うには、以下の処理を行う必要がある。

1. トランザクションひな型の取得
2. トランザクションへの署名
3. 署名済みトランザクションを Blockchain P2P ネットワークへブロードキャスト

これらの処理は、以下のコマンドを実行するとで完了する。

```
> curl -s {トランザクション作成用ページから取得した Link の URL} | ^
key-forge -j -k {取引用に作成した (Bob の) PrivateKey} | ^
curl -X POST -d @- -H "content-type: application/json" https://testnet.litecore.io/api/tx/send
```

上記のコマンドの各行は、上記手続きに対応している。

トランザクションは、払い戻し制限日時経過後でないと、承認されない。払い戻し制限日時以前でも、上記コマンドでトランザクション送信を行うことはできるが、

```
64: non-final. Code:-26
```

というエラーで、無効となる。制限日時経過後、改めて送信すれば、承認されるだろう。

トランザクションが承認されれば、受け取り用ウオレットアドレスに入金が行われる。

### この取引の例

https://nora.noumia.net/htlc/tltc/Qg8sWJsw6ep6aQR2DRXyLuqkAU8ZmyFnhn


## トランザクション送信用コマンドの具体例

```
> curl -s https://nora.noumia.net/api/tltc/tx/mPWljs0sb3Wxy7S_bPvxPxtP27wX | ^
key-forge -j -k c*********************************************3xEW6m | ^
curl -X POST -d @- -H "content-type: application/json" https://testnet.litecore.io/api/tx/send
```

### 1行目

トランザクションひな型の JSON を取得して、パイプで送り出す。
ページに表示されている JSON と同じなので、ブラウザからコピー＆ペーストしてもよい。

### 2行目

トランザクションひな型に署名処理を行い rawtransaction (hexstring) を生成する。
-j オプションは、JSON での出力。

PrivateKey は、一部伏字としている。

### 3行目

rawtransaction を P2P ネットワークへブロードキャストする。
公開 API を使用して送出を行っているが、RPC 'sendrawtransaction' command 等で、自分のノードから送出することもできる。