State Hash その１ subCacheMerkleRootsからstateHashの計算

# はじめに

そろそろ避けていたものに手を付けなければ

今回は、subCacheMerkleRootsとstateHashの関係に注目します。

# State Hash

[catapult-service-bootstrap](https://github.com/tech-bureau/catapult-service-bootstrap)などを動かした際、標準出力にこのようなものが出力されると思います。


```
           Height: 1
  Generation Hash: 5ABBD9F7894EE7E5D4C3CDA934245396AEFCD1CB0426F265AC81F4F3450AB6DD
Transactions Hash: 111461D150B90EBF58A87AB2FA2493DCB716F83E7EE584369820D6CA10DE5E52
    Receipts Hash: A207227B111F4242DE80FC87E722B86077931B483883EA65E06A24340176A047
       State Hash: BDCAF08330E29EBC7F18A1A9E6C7C60E4CFF99B100FC583FCDBAFA6F875F5DCF
--- Components (7) ---
 + 779F9E5BCEFB8267C084B14F8C2CB981683E6715BAFF4DC3B39BC133AFBEDD1B
 + 7BA3B37CDF34608C3B98BE572C7A743FEAC8B6909654AF21B8E0F4381EFD9164
 + 5D8EEAD5907130D297C322698F3D201A78D629CAC87487A0F4F890C1277B250C
 + 0000000000000000000000000000000000000000000000000000000000000000
 + 0000000000000000000000000000000000000000000000000000000000000000
 + 0000000000000000000000000000000000000000000000000000000000000000
 + 0000000000000000000000000000000000000000000000000000000000000000
```

これらは、ブロックチェーンの状態（ステート）を表す値で、`Components (7)`の値はそれぞれ次のようなステートを表しています。

>Finally COW state roots in order:
 * account state cache (balances)
 * namespace cache
 * mosaic cache
 * multisig cache
 * hash lock cache
 * secret lock cache
 * property cache

https://twitter.com/NCOSIGIMCITYNRE/status/1091312286822813696

それで、これらの値を代表するものが`State Hash`です。

# 計算してみる

代表しているってなんやねんということですが、とりあえず計算してみましょう。

とあるチェーンのブロック番号600000のステートを見てみます。

http://13.114.200.132:3000/block/600000

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/148bbeae-9718-1c50-a84e-a3c0a2fee078.png)

stateHashは
`5A4AB7830E7CE281252ED3CBADC5A7919A5DF82BA0766788186EC32308934B37`


subCacheMerkleRootsは

```
0	"4401DAC79E1CDBB6903BED8F6CE5D6BB29DF9220D65D1093644968C61DCE5490"
1	"99DCAAB775F4D905A43446A54336A7C52C011D0B036D92E3DEA77A6B4806130D"
2	"30A245258080BA6825F4263AEF2146C2B899FE8891B5E528EFE4C861397FFB8C"
3	"3BD4B1669FAC87AF68A1DB54AE737A0227A3D0B85AECB3A0FF7240E228731715"
4	"0000000000000000000000000000000000000000000000000000000000000000"
5	"0000000000000000000000000000000000000000000000000000000000000000"
6	"A13E3FB1B22964DC32FE77DAB978617F3CB15B3930371D6D4477BE47C961AE47"
```

さて、`subCacheMerkleRoots`をすべて文字列結合してsha3してみます。

sha3(4401DAC79E1CDBB6903BED8F6CE5D6BB29DF9220D65D1093644968C61DCE549099DCAAB775F4D905A43446A54336A7C52C011D0B036D92E3DEA77A6B4806130D30A245258080BA6825F4263AEF2146C2B899FE8891B5E528EFE4C861397FFB8C3BD4B1669FAC87AF68A1DB54AE737A0227A3D0B85AECB3A0FF7240E22873171500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A13E3FB1B22964DC32FE77DAB978617F3CB15B3930371D6D4477BE47C961AE47)

結果は、

5A4AB7830E7CE281252ED3CBADC5A7919A5DF82BA0766788186EC32308934B37

`stateHash`と一致します。

コードはこんな感じになるかと思います。

```javascript
const jssha3 = require('js-sha3');
const payload = '4401DAC79E1CDBB6903BED8F6CE5D6BB29DF9220D65D1093644968C61DCE549099DCAAB775F4D905A43446A54336A7C52C011D0B036D92E3DEA77A6B4806130D30A245258080BA6825F4263AEF2146C2B899FE8891B5E528EFE4C861397FFB8C3BD4B1669FAC87AF68A1DB54AE737A0227A3D0B85AECB3A0FF7240E22873171500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A13E3FB1B22964DC32FE77DAB978617F3CB15B3930371D6D4477BE47C961AE47';
const hasher = jssha3.sha3_256.create();
const hash = hasher.update(Buffer.from(payload, 'hex')).hex().toUpperCase();
console.log(hash);
```

# おわりに

`subCacheMerkleRoots`のsha3をとったら`stateHash`になりました。`stateHash`から`subCacheMerkleRoots`は導出できませんが、`subCacheMerkleRoots`が1バイトでも変更されると、`stateHash`の値が変わります。これにより、例えば、`stateHash`にだけ署名をつけたり、ブロックのデータとして取り込んだりすることにより、`subCacheMerkleRoots`が何か別の値に変えられていたりするのを防ぐことができます。

# シリーズ

[State Hash その１ subCacheMerkleRootsからstateHashの計算](https://qiita.com/planethouki/items/4e411a9b157e723327ee)

[State Hash その２ 要素が1つだけの場合のsubCacheMerkleRootsの計算](https://qiita.com/planethouki/items/a905c543829dba2331d3)

[State Hash その２追記](https://qiita.com/planethouki/items/03cc5ac3b655f7bd1f45)

[State Hash その３ 要素が2つの場合のPatricia Tree](https://qiita.com/planethouki/items/3f7a235de3fb347bcb4d)