Crate eth_twc_sdk

Crate eth_twc_sdk 

Source
Expand description

§eth-twc-sdk

TransferWithCommitment(TWC) 向け Ethereum クライアント SDK(EIP-712・コントラクト呼び出し・レシート検証)。

§Usage

  1. TWC アドレス — 通常ビルドでは config のソース(transfer_with_commitment_address が返すコンパイル時定数)をデプロイ先に合わせる。integration-test 時のみ環境変数 ETH_TWC_CONTRACT_ADDRESS を参照します。
  2. プロバイダ — Alloy の Provider(例: ProviderBuilder::new().connect_http(url))を用意します。
  3. 送金 — EIP-712 委任なら sign で署名バンドルを作り send_transaction::signature_transfer で送信。msg.sender 送金なら send_transaction::self_transfer を直接呼びます。
  4. 検証 — マイニング後のトランザクションハッシュと VerifyArgsverify を呼び、レシート上の TransferWithCommitmentSent を照合します。

msg.sender で送金して検証する例(接続チェーンの config::transfer_with_commitment_address に TWC がデプロイ済みであること)。

use alloy::primitives::{address, utils::parse_ether, B256};
use alloy::providers::ProviderBuilder;
use eth_twc_sdk::{
    send_transaction::self_transfer,
    types::SelfSingleTransferArgs,
    verify,
    VerifyArgs,
};

#[tokio::main]
async fn main() -> Result<(), eth_twc_sdk::SdkError> {
    let provider = ProviderBuilder::new().connect_http("http://127.0.0.1:8545".parse().unwrap());
    let from = address!("0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266");
    let token = address!("0x5FbDB2315678afecb367f032d93F642f64180aa3");
    let to = address!("0x70997970C51812dc3A010C7d01b50e0d17dc79C8");
    let value = parse_ether("1").unwrap();
    let commitment = B256::ZERO;

    let args = SelfSingleTransferArgs {
        token,
        to,
        value,
        commitment,
    };
    let tx_hash = self_transfer::transfer(&provider, from, args).await?;

    verify::verify(
        &provider,
        tx_hash,
        &VerifyArgs {
            from,
            token,
            to,
            value,
            commitment,
        },
    )
    .await?;
    Ok(())
}

EIP-712 署名を executor が送信し、同じく検証する例(読み取り用 Provider・署名者・executor 用ウォレット付き Provider)。

use alloy::network::EthereumWallet;
use alloy::primitives::{address, utils::parse_ether, B256};
use alloy::providers::ProviderBuilder;
use alloy::signers::local::PrivateKeySigner;
use eth_twc_sdk::{
    send_transaction::signature_transfer,
    sign,
    types::SingleTransferArgs,
    verify,
    VerifyArgs,
};

#[tokio::main]
async fn main() -> Result<(), eth_twc_sdk::SdkError> {
    let read_provider =
        ProviderBuilder::new().connect_http("http://127.0.0.1:8545".parse().unwrap());

    let sender: PrivateKeySigner =
        "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
            .parse()
            .unwrap();
    let executor: PrivateKeySigner =
        "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"
            .parse()
            .unwrap();

    let token = address!("0x5FbDB2315678afecb367f032d93F642f64180aa3");
    let to = address!("0x70997970C51812dc3A010C7d01b50e0d17dc79C8");
    let value = parse_ether("1").unwrap();
    let commitment = B256::ZERO;

    let signed = sign::single_transfer(
        &read_provider,
        &sender,
        SingleTransferArgs {
            from: sender.address(),
            to,
            token,
            executor: executor.address(),
            value,
            commitment,
            valid_after: None,
            valid_before: None,
        },
    )
    .await?;

    let executor_provider = ProviderBuilder::new()
        .wallet(EthereumWallet::new(executor.clone()))
        .connect_http("http://127.0.0.1:8545".parse().unwrap());
    let tx_hash =
        signature_transfer::single_transfer(&executor_provider, executor.address(), signed).await?;

    verify::verify(
        &read_provider,
        tx_hash,
        &VerifyArgs {
            from: sender.address(),
            token,
            to,
            value,
            commitment,
        },
    )
    .await?;
    Ok(())
}

§Commitment(B256)の導出 — 利用者向け注意

本クレートは commitment を生成するヘルパを提供しない。理由は、(1) 外部とランダム nonce を共有するスキームなど、アプリ層のスキーマとの相互運用性を SDK で固定しないため、(2) ハッシュ関数の選択を SDK に押し付けず、ハッシュに関する単一障害点にならないためである。

オフチェーンで commitment を導出するときは、利用者の責任で 暗号学的にランダムな r と、用途に適した安全なハッシュ関数 H を選び、少なくとも commitment = H(message || r) の形(message はアプリのスキーマに従うバイト列)を満たすことを推奨する。H の具体(例: Keccak-256)や message のエンコードは、アプリと合意者間で定義する。

§構成

モジュール役割
config決定論 TWC アドレス・EIP-712 / CREATE2 salt 定数
signEIP-712 署名(Provider + Signer
verifyトランザクションレシート上のイベント検証
send_transaction::self_transfermsg.sender による transfer
send_transaction::signature_transfer署名付き transferWithAuthorization / cancelAuthorization
types引数・署名済みバンドル・明細型
utilsチェーン/domain 整合の検証ヘルパ
eventsログデコード用イベント型

オンチェーン呼び出し・型生成は alloy に依存します。

§クイックリンク

§ドキュメントの生成

cargo doc --no-deps

非公開モジュール(contract など)を含める場合は --document-private-items を付けます。

Re-exports§

pub use config::transfer_with_commitment_address;
pub use error::SdkError;
pub use types::signed_data::SignedBatchTransferWithCommit;
pub use types::signed_data::SignedCancelAuthorization;
pub use types::signed_data::SignedTransferWithCommit;
pub use types::signed_data::SignedUniCommitTransfers;
pub use verify::VerifyArgs;
pub use events::TransferWithCommitmentSent;
pub use utils::assert_provider_supported_chain;
pub use utils::assert_signed_domain_matches_client_and_config;
pub use utils::assert_signed_domain_matches_provider_and_config;

Modules§

config
コントラクトアドレスと CREATE2 / EIP-712 の固定パラメータ。
error
SdkError — SDK 各 API で返りうるエラー。
events
レシート解析用の sol! イベント定義。 トランザクションレシートのログからイベントをデコードするための定義(コントラクト ABI と同一シグネチャ)。
send_transaction
トランザクション送信(自己送金・署名付き)。 コントラクトへのトランザクション送信。
sign
EIP-712 オフチェーン署名。
types
送金引数・署名済みバンドル・明細行の型定義。
utils
チェーン検証および EIP-712 domain と設定アドレスの照合。
verify
トランザクションレシート上の TransferWithCommitmentSent イベントの取得・検証。

Structs§

Address
Ethereum アドレス(alloy::primitives::Address の再エクスポート)。 An Ethereum address, 20 bytes in length.
Eip712Domain
EIP-712 ドメイン(alloy::sol_types::Eip712Domain の再エクスポート)。 EIP-712 domain attributes used in determining the domain separator.