トップレベルのプロパティ
Sequence v2の設定には、以下の3つのプロパティが含まれます。threshold- 署名が有効とみなされるために必要な「重みの合計」です。checkpoint- ウォレットの更新時のソルトや順序管理に使用されます。tree- ウォレットの署名者とその重みを決定します。
しきい値
thresholdはuint16型で、0から65535までの値を取ります。署名者の重みの合計がthreshold以上の場合のみ、署名は有効とみなされます。
チェックポイント
checkpointはuint32型です。ウォレット作成時に、同じ初期設定で独立したウォレットを生成するために半ランダムな値を指定できます。通常運用時は、Light State Syncによってウォレット更新が正しい順序で適用されるようにcheckpointが使われます。
ツリー
treeはアンバランスなバイナリMerkleツリーで、各リーフには署名者、静的署名、またはサブツリーが含まれます。このツリーにより、あらゆる組み合わせの署名者と重みを表現でき、複雑なマルチシグウォレットの作成も可能です。
リーフの種類は以下の通りです。
署名者
署名者は署名者のaddressとuint8の重みで表されます。重みは、その署名者がthresholdにどれだけ貢献するかを示します。
アドレスはERC1271準拠のコントラクトまたはEOAウォレットのいずれかです。
リーフハッシュは以下のように計算されます。
サブダイジェスト
これは、どんな署名でも有効となる静的なサブダイジェストを表します。このサブダイジェストに対する署名が提供された場合、その署名の重みは自動的にInfinityとなります。
ネストされたツリー内に存在する静的サブダイジェストは、その「Infinity」重みがネストされたツリーの重みに減少します。
リーフハッシュは以下のように計算されます。
サブツリー(ネストされた設定)
これは新しいウォレット設定全体を表し、この「ネストされた設定」には、以下の独自要素が含まれます。- 外部
weight(uint8) - 内部
threshold(uint16) - 内部
tree
internal thresholdに達する署名があれば有効とみなされ、external weightが親ツリーに加算されます。ネストされた設定はいくつでも作成でき、複数階層のネストも可能です。
このパターンは、例えば、以下のようなシナリオを表現する際に利用できます。
- 非線形の重み分配:AとBの署名者はそれぞれ1の重みを持つが、2人揃うと3の重みになる。
- 合計重みの制限:A、B、Cの署名者はそれぞれ1の重みを持つが、3人揃っても合計2の重みしか提供できない。
- 「部門ごとの設定」:N個の部門が署名を必要とし、それぞれの部門が独自の内部設定を持つ。
イメージハッシュ
configuration全体が保存されることはなく、Merkleツリーを単一のbytes32値にハッシュ化します。これを内部的に設定のimageHashと呼びます。
imageHashは以下のように計算されます。
hashTree関数はツリー全体を再帰的にハッシュ化して単一のbytes32値にします。hashTree関数の擬似コードは以下の通りです。
初期設定
すべてのSequenceウォレットには「初期設定」があり、ウォレットのCREATE2デプロイ時に初期設定のimageHashをSALTとして使用します。
ウォレットはFactoryコントラクトのdeploy関数を呼び出してデプロイされます。この関数には以下のパラメータを指定します。
mainModule: ウォレットの初期コード実装のアドレス。salt: 初期設定のimageHash。
ウォレットの初期コード実装には常に
MainModuleを使用してください。MainModuleは(署名検証時に)imageHashを再計算してカウンターファクチュアルアドレスを検証するため、ストレージの初期化は不要です。もしimageHashが変更された場合、MainModuleは自動的にウォレットのコード実装をMainModuleUpgradeableに置き換え、ストレージの初期化も行います。