最近のWeb3関連のキャッチアップ

# はじめに
本職ではあまりスマートコントラクトに触れる機会があまりなく、流行りについてなんとなく知っている程度だったのでSolidityのリハビリのためにもよく聞くな〜って事柄を書き残す。ちなみに筆者は2.3年前に少しSolidityを齧った程度なので浦島太郎状態古い情報しかないので、よく書く人にとっては当たり前の情報かもしれないのと自分の理解のためのメモでもあるので見やすさ等はご了承。
また細かい部分の実装の深掘りはしないのである程度筋がわかる程度の理解のみをつらつら書き残す。

内容
* スマートコントラクト実装
    * Smart Contract Wallet
    * MPC Wallet
* ERC
    * ERC-4337 Account Abstraction
    * ERC-6551 Non-fungible Token Bound Accounts
* サービス
    * Lit Protocol
    * LIDO リキッドステーキング
    * Eigen Layer リステーキング

# スマートコントラクト実装
## Smart Contract Wallet

その名の通り、Smart Contractでのwallet。
特徴としては、
+ Smart Contractなので秘密鍵がない
+ スマコンのコードでWalletの操作に制約をかけることができる(以下Safe walletでの例)
    + マルチシグWallet
        + 複数人で1つのEOAのwalletを扱うとプライバシー的な面で秘密鍵管理がしんどい。事前に決められた人がそれぞれ持つEOAで署名をもらうとトランザクションを実行できるようにする
    + タイムロック
        + 再度特別な承認を求めなくても設定した時間によりトランザクションを実行することができる
    + 閾値署名
        + 特定の数の署名をもらうとトランザクションが実行できるようになる。マルチシグwalletより署名の取得先が柔軟

<details><summary>[僕のわからんポイント] なんとなくWalletっぽいスマコンは想像つくけどトランザクション実行部分ってどういうコードなんだろう...?
</summary>

参照コード：https://github.com/safe-global/safe-smart-account/blob/main/contracts/Safe.sol

safe.sol
```js
    // Transaction実行部分
    function execTransaction(
        address to,
        uint256 value,
        bytes calldata data,
        Enum.Operation operation,
        uint256 safeTxGas,
        uint256 baseGas,
        uint256 gasPrice,
        address gasToken,
        address payable refundReceiver,
        bytes memory signatures
    ) public payable virtual override returns (bool success) {
        bytes32 txHash;
        // Use scope here to limit variable lifetime and prevent `stack too deep` errors
        {
            txHash = getTransactionHash( // Transaction info
                to,
                value,
                data,
                operation,
                safeTxGas,
                // Payment info
                baseGas,
                gasPrice,
                gasToken,
                refundReceiver,
                // Signature info
                // We use the post-increment here, so the current nonce value is used and incremented afterwards.
                nonce++
            );
            checkSignatures(txHash, signatures);
        }
        address guard = getGuard();
        {
            if (guard != address(0)) {
                Guard(guard).checkTransaction(
                    // Transaction info
                    to,
                    value,
                    data,
                    operation,
                    safeTxGas,
                    // Payment info
                    baseGas,
                    gasPrice,
                    gasToken,
                    refundReceiver,
                    // Signature info
                    signatures,
                    msg.sender
                );
            }
        }

        if (gasleft() < ((safeTxGas * 64) / 63).max(safeTxGas + 2500) + 500) revertWithError("GS010");
        {
            uint256 gasUsed = gasleft();
            success = execute(to, value, data, operation, gasPrice == 0 ? (gasleft() - 2500) : safeTxGas);
            gasUsed = gasUsed.sub(gasleft());
            if (!success && safeTxGas == 0 && gasPrice == 0) revertWithError("GS013");
            uint256 payment = 0;
            if (gasPrice > 0) {
                payment = handlePayment(gasUsed, baseGas, gasPrice, gasToken, refundReceiver);
            }
            if (success) emit ExecutionSuccess(txHash, payment);
            else emit ExecutionFailure(txHash, payment);
        }
        {
            if (guard != address(0)) {
                Guard(guard).checkAfterExecution(txHash, success);
            }
        }
    }

```

safe walletのexec関数
```js
...
abstract contract Executor {
    function execute(
        address to,
        uint256 value,
        bytes memory data,
        Enum.Operation operation,
        uint256 txGas
    ) internal returns (bool success) {
        if (operation == Enum.Operation.DelegateCall) {
            /* solhint-disable no-inline-assembly */
            /// @solidity memory-safe-assembly
            assembly {
                success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)
            }
            /* solhint-enable no-inline-assembly */
        } else {
            /* solhint-disable no-inline-assembly */
            /// @solidity memory-safe-assembly
            assembly {
                success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)
            }
            /* solhint-enable no-inline-assembly */
        }
    }
}
```

EOA Walletのトランザクションの実行は署名データをスマートコントラクトWalletに渡して代わりに実行してもらうと言う感じなのね〜
署名済みトランザクションデータがあったらそれをスマコンは実行できるのね
Safe Walletでは`Enum.Operation`で`DelegateCall`か`Call`かがあるらしいが、この辺はどう使い分けて使っているんだろう...?

</details>

## MPC Wallet
MPC(マルチパーティ計算)を使って秘密分散をベースにセキュアなWallet管理をすることができる。

Binance Academyのサイトがかなり分かりやすくまとまっているのでチェケラ

マルチシグウォレットとの違い
> マルチシグウォレットは、2つ以上の秘密鍵（各当事者から1つずつの秘密鍵）による認証を必要とする独特の署名をもってブロックチェーントランザクションを送信します。一方MPCウォレットは、1つの秘密鍵を複数の当事者間で分割します。両者は似ているように聞こえるかもしれませんが、技術的にはMPCウォレットはより柔軟かつ実装しやすいものとなっています。
> ([Binance Academyより](https://academy.binance.com/ja/articles/what-are-multi-party-computation-mpc-wallets))

特徴
> * プライバシーの向上：すべてのデータ処理過程は暗号化され、第三者への信頼に依存する必要がありません。
> * セキュリティの向上：単一障害点を排除します。秘密鍵は、複数の当事者や場所に分散管理されます。
> * より高い利便性：資産をオンライン上に保管できます。コールドストレージは必要ありません。

Fireblocksとかが有名らしいので今度触ってみる(https://www.fireblocks.com/)

# ERC系

## ERC-4337 Account Abstraction
Account Abstractionは和訳すると「アカウント抽象化」
イーサリアムのネットワークから見て、EOAかスマコンかが抽象化されるため、アカウントとして同一視される。
スマコンWalletを使って複数のトランザクションを実行する。
この時、複数のトランザクションをまとめるEOAアカウントをBundlerといい、そのトランザクションを実行するコントラクトをEntry pointという。

ガス代の肩代わりのロジックを組めたり、ECDSA以外の署名アルゴリズムを使えたり、ソーシャルリカバリーができたりと、UXとセキュリティが改善する。


## ERC-6551 Non-fungible Token Bound Accounts
https://eips.ethereum.org/EIPS/eip-6551

ERC6551はERC721のNFTごとにスマートコントラクトウォレットを作成して、アドレスを付与することで、
NFTがアカウントとしてFT・NFTを持つことができる



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382669/bc21627a-f5ab-a009-fe07-70a5e896b5e5.png)
画像引用：[「ERC-6551」とは](https://ethereumnavi.com/2023/12/24/erc-6551/)

例えば、ドメイン系(ENS等)のNFTをNFTやEther等を管理できるWalletとして扱うことができるっぽい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382669/e79891dc-a2b3-5f63-c6c1-e7d9a7f0956e.png)
画像引用：[新星 🌠 Shinsei Galverse X Post](https://twitter.com/galverseNFT/status/1691246591779516416)

親NFTに紐付いているに紐付いているNFTを別のアドレスに移動したい場合は親NFTを移動すればまとめて移動できるので
* 別のwalletへのお引越し
* NFT・FTのまとめ売り
ができる

ERC-6551にするのは親NFTだけでいいので、子NFTに関しては従来の規格をそのまま使える下位互換性があるのもポイントらしい

広い意味でのDecentralized Identity(W3Cの標準ではなく)が活用される先になりそう

# サービス
## Lit Protocol
Lit Protocolは、閾値暗号化を活用した分散型キー管理ネットワークおよびプラットフォームで、ブロックチェーンに依存しないミドルウェア層で展開される。

閾値暗号自体は秘密分散で用いられる割と昔からある技術らしく、ある情報をn個の分割情報にした際に決められたk個以上の分割情報があると復元できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382669/9889eece-ba23-d715-af6f-e31b9ea582bd.png)
引用：[注目の情報管理方式「しきい値秘密分散法」](https://atmarkit.itmedia.co.jp/fsecurity/special/53tsss/tsss02.html)

Lit Protocolでは分散鍵生成(DKG)と呼ばれるプロセスで暗号鍵のペアを秘密分散としてネットワークで管理でき、ネットワークに参加するノードの2/3がしきい値として設定されている

使用例については公式からチェック
https://developer.litprotocol.com/v3/concepts/access-control-concept#exploring-decentralized-access-control-with-lit

これは触ってみないとどれくらい便利かわからなそうなので今度使ってみたいと思っている

## LIDO リキッドステーキング

リキッドステーキングとは、Ethereumのバリデータノードを代理運用(代わりにステーキング)してもらい、その報酬をもらうことができる。(ステーキング報酬)
Ethereumをバリデータに預けたら、預けたEthereumを使うことは引き出さない限り使用できなくが、リキッドステーキングし、そのサービスに預けている事実をトークン化することでそのトークンを使うことができる。
ノードの運用者もEthを必要とせずにvalidatorとして運用できる。

<details><summary>Q.どんな流れで報酬は得られるんだろうか？
</summary>
報酬が作られる流れ
1. UserがLIDOコントラクトにETHを預ける
2. LIDOにいるバリデータノードがブロックを生成する
3. 生成報酬をLIDOコントラクトが受け取る
4. LIDOコントラクトが計算式に基づいてバリデータとUserに分配される
</details>

LIDOは一番使われているリキッドステーキングサービス。

https://lido.fi/


## Eigen Layer リステーキング

EthereumのバリデータノードとしてEthをステーキングしたことを担保にまた再ステーキング(リステーキング)できるサービス。
Ethを直接リステーキングすることもリキッドステーキングしているトークンもリステーキングすることができる。


https://defire.jp/eigen-layer/

> 1つ目は、バリデーターがイーサリアムをリステーキングすることで報酬を得ることができるため、イーサリアムの需要が増し、価格の上昇が期待できる点です。
> 2つ目はバリデーターが増えることで取引を検証する人が増えるということはイーサリアムのセキュリティが強くなり、さらにEigen Layer上で構築されたプロジェクトはイーサリアムのセキュリティを借りることができる点です。


参考文献
+ Account Abstraction
[Account Abstraction とは何か？ ブロックチェーンの体験を変えるERC4337について](https://tech.hashport.io/4143/)
[ERC 4337: account abstraction without Ethereum protocol changes](https://medium.com/infinitism/erc-4337-account-abstraction-without-ethereum-protocol-changes-d75c9d94dc4a)

+ ERC6551
https://blog.thirdweb.com/erc-6551-token-bound-accounts/
https://ethereumnavi.com/2023/12/24/erc-6551/ 

+ Lit Protocol
https://zenn.dev/moneyforward/articles/8c666a192b88bd