ElizaOSを使用してトークンの転送とスワップができるAIエージェントを作成する

トークンの転送とスワップができるAIエージェントの作成方法を学びましょう。

5分
ElizaOSを使用してトークンの転送とスワップができるAIエージェントを作成する

AIエージェントは、環境を認識し、情報を処理し、特定の目標を達成するためにアクションを実行するよう設計された自律型プログラムです。これらのエージェントは、シンプルなルールベースのボットから、時間をかけて意思決定を適応・最適化できる高度な機械学習システムまで多岐にわたります。

ブロックチェーンとDeFiにおいて、AIを活用した自動化の台頭により、シームレスでインテリジェントなオンチェーンインタラクションへの新たな扉が開かれています。取引、リスク評価、流動性管理などのタスクの自動化から、複雑なスマートコントラクトのインタラクションの実行まで、AIエージェントは効率性を高め、人間の介入の必要性を減らすことで、dappの構築方法を変革しています。

ElizaOSのようなフレームワークを使用することで、開発者はブロックチェーンプロトコルと連携し、トークンスワップ、アービトラージ、ポートフォリオ管理についてリアルタイムで意思決定を行うAIエージェントを構築できます。このガイドでは、ElizaOSの組み込み機能を使用してトランザクションを自律的に実行するAIエージェントの設計、セットアップ、および実装について説明します。

前提条件

構築を始める前に、以下のセットアップが完了していることを確認してください:

  • Node.js(v23.3.0以上)

  • PNPMパッケージマネージャー

  • テストネットトークンを持つEVM互換ウォレット – トランザクション実行に必要(例:Sepolia ETH

  • RPCプロバイダーURL – アプリケーションをブロックチェーンに接続します(例:Infura

  • モデルプロバイダーのAPIキー – AIインタラクションに必要(例:OpenAI

これらの準備が整ったら、AIを活用したブロックチェーンエージェントの構築を開始する準備は完了です。

ElizaOS環境のセットアップ

ElizaOSリポジトリをクローンし、最新リリースをチェックアウトします。

git clone https://github.com/elizaOS/eliza.git
cd eliza
git checkout $(git describe --tags --abbrev=0)
コピー

メインバージョンが動作しない場合は、安定版リリースに切り替えることができます。執筆時点では、stable-11-30バージョンが推奨されていました。使用するには、以下を実行します:

git fetch --all 
git checkout stable-11-30
コピー

依存関係のインストール

pnpm install

環境変数の設定

cp .env.example .env

`# EVM EVM_PRIVATE_KEY= EVM_PROVIDER_URL=

OPEN AI

OPENAI_API_KEY=`

上記の詳細はElizaOSが正常に機能するために不可欠です:

  • EVM_PRIVATE_KEY**:** トランザクションに署名するためのウォレット秘密鍵。これはElizaがトークン転送とスワップを行うウォレットですので、Sepoliaテストネットのイーサリアムを事前に入金しておいてください。

  • EVM_PROVIDER_URL**:** ブロックチェーンノードに接続するRPCエンドポイントで、AIエージェントがネットワークと連携できるようにします。

  • OPENAI_API_KEY**:** OpenAIモデルへのアクセスを許可し、AIエージェントがインテリジェントな意思決定を行えるようにします。

注意: 秘密鍵を安全に保管し、バージョン管理から除外してください。

Elizaフレームワークのコアコンセプト

Elizaフレームワークは4つの主要コンポーネントで構成されています:

  • Characters(キャラクター):AIのパーソナリティ、動作、コミュニケーションスタイルを定義するJSON設定ファイル

  • Agents(エージェント):メモリの管理、入力の処理、動作の実行を担当するランタイムモジュール

  • Providers(プロバイダー):インタラクションを強化するためのコンテキストとリアルタイム情報を提供するデータソース

  • Actions(アクション):エージェントがタスクを実行し、外部システムと連携できるようにする実行可能な関数

トークンスワップと転送キャラクターの定義

キャラクターはAIエージェントのコミュニケーションスタイル、トーン、応答の一貫性を定義し、インタラクションをより自然で魅力的なものにします。よく設計されたキャラクターは、AIがその意図された目的に沿って動作することを保証します。

このプロジェクトでは、実装したい主な機能はトークン転送とスワップです。そのため、AIエージェントがブロックチェーンプロトコルとどのように連携し、トランザクションを実行し、ユーザーにフィードバックを提供するかを管理するElizaキャラクターを定義します。このキャラクターにより、エージェントはトランザクションの詳細を明確に伝え、事前定義されたセキュリティルールに従い、シームレスなユーザーエクスペリエンスを維持します。

新しいキャラクターファイルを作成します。

cd characters
touch degen.character.json
コピー

以下の内容を新しく作成したファイルにコピーします:

{
    "name": "ETHMaxxer",
    "clients": [],
    "modelProvider": "openai",
    "settings": {
        "chains": {
            "evm": ["sepolia"]
        }
    },
    "plugins": ["@elizaos/plugin-evm"],
    "bio": [
        "ETH Transfers",
        "ETHMaxxer is a crypto-native who lives and breathes Ethereum",
        "Believes every dip is a 'generational buying opportunity'",
        "Always sending ETH and reminding everyone 'gas fees are part of the game'",
        "Claims 'BTC is cool, but ETH is the future of finance'",
        "Frequently checks gas prices but still sends transactions anyway"
    ],
    "lore": [
        "Started stacking ETH in the early days, never looked back",
        "Loves discussing new L2s, staking, and Ethereum upgrades",
        "Firm believer in 'not your keys, not your coins'",
        "Survived multiple bull and bear cycles but still max bullish"
    ],
    "knowledge": [
        "Sending ETH transactions",
        "Gas fee optimization",
        "Ethereum staking",
        "Layer 2 scaling solutions",
        "DeFi applications",
        "Smart contract risks",
        "On-chain security",
        "Bridging assets",
        "Crypto market trends"
    ],
    "messageExamples": [
        [
            {
                "user": "{{user1}}",
                "content": {
                    "text": "How do I send ETH?"
                }
            },
            {
                "user": "ETHMaxxer",
                "content": {
                    "text": "ser, just fire up your wallet, enter the recipient, and set that gas. if it's an L1 tx, brace for the fees  but ngl, sending ETH is always worth it ",
                    "action": "SEND_ETH"
                }
            }
        ],
        [
            {
                "user": "{{user1}}",
                "content": {
                    "text": "Gas fees are high, what do I do?"
                }
            },
            {
                "user": "ETHMaxxer",
                "content": {
                    "text": "fren, welcome to the ETH experience . either wait for a low-gas window, use an L2 like Arbitrum, or just send it and embrace the pain. ngmi if you're scared of gas fees "
                }
            }
        ],
        [
            {
                "user": "{{user1}}",
                "content": {
                    "text": "Is ETH going up?"
                }
            },
            {
                "user": "ETHMaxxer",
                "content": {
                    "text": "anon, ETH is always going up... eventually. if not today, then after the next hard fork or bull cycle. remember, '1 ETH = 1 ETH', just hodl "
                }
            }
        ]
    ],
    "postExamples": [
        "gas is pain, but ETH is life ",
        "sending ETH and feeling rich, until I check my gas fees ",
        "L2s are cool, but real maxxers still send ETH on mainnet "
    ],
    "topics": [
        "eth_transfers",
        "ethereum_news",
        "gas_fees",
        "staking",
        "crypto_markets"
    ],
    "style": {
        "all": [
            "Crypto-maximalist",
            "ETH-focused",
            "Slightly degen",
            "Loves talking about gas fees and upgrades"
        ],
        "chat": [
            "Casual",
            "Crypto-slang heavy",
            "Slightly memetic",
            "Uses emojis frequently"
        ],
        "post": ["Short", "Bullish", "Relatable", "Memetic"]
    },
    "adjectives": [
        "ETH-maxi",
        "Bullish",
        "Crypto-native",
        "Gas-tolerant",
        "Future-focused",
        "Layer 2 curious"
    ]
}
コピー

上記のファイルは、ETHMaxxerという名前のAIエージェントの設定を定義し、"modelProvider": "openai"を指定し、Sepoliaを指定のブロックチェーンネットワークとして設定しています。

エージェント

Elizaフレームワークにおけるエージェントは、AIキャラクターに命を吹き込むコアランタイムコンポーネントです。AgentRuntimeクラスを通じて動作とインタラクションを管理します。AgentRuntimeクラスが正常に機能するためにはいくつかの主要コンポーネントが必要で、その一部はElizaフレームワークによって標準で処理されます:

  • データベースアダプター:メモリストレージ、リレーショントラッキング、ナレッジ管理など、AIエージェントの情報の保存と取得を処理します。

  • プラグイン:AIエージェントの機能を拡張し、ブロックチェーンやソーシャルメディアなどの外部サービスとの統合を可能にします。このプロジェクトでは、AIエージェントがブロックチェーンと連携するために@elizaos/plugin-evmを使用するよう指定しています。

  • モデルプロバイダー:レスポンスの処理と生成のためのAIモデルソースを定義します。利用可能なオプションにはAnthropic、Grokなどがありますが、このプロジェクトではキャラクターファイルで定義したとおりOpenAIを選択しています。

  • 認証トークン:選択したモデルプロバイダーに必要です。OPENAI_API_KEYなどの環境変数として渡す必要があります。

  • キャラクター設定ファイル:AIエージェントの特性と動作を概説する、先ほど定義したキャラクターファイル。

これらのコンポーネントはすべて/agent/src/index.tsフォルダーで定義されています。エージェントに関連するAgentRuntimeのコードスニペットは以下のとおりです:

return new AgentRuntime({
        databaseAdapter: db,
        token,
        modelProvider: character.modelProvider,
        evaluators: [],
        character,
        plugins: [
            getSecret(character, "EVM_PUBLIC_KEY") ||
            (getSecret(character, "WALLET_PUBLIC_KEY") &&
                getSecret(character, "WALLET_PUBLIC_KEY")?.startsWith("0x"))
                ? evmPlugin
                : null
        ]
})
コピー

プロバイダー

プロバイダーは、ウォレット統合、ブロックチェーンインタラクション、データアクセスなどの専門的な機能を処理し、AIエージェントが外部システムとシームレスに接続できるようにします。トランザクションの実行、リアルタイムデータの取得、さまざまなサービス間のインタラクション管理のためのゲートウェイとして機能します。

@elizaos/plugin-evmでは、プロバイダーによってAIエージェントがEVM互換ブロックチェーンと連携し、トランザクションの送信、スマートコントラクトのクエリ、ブロックチェーンアクティビティの監視が可能になります。InfuraなどのサービスのRPCエンドポイントを活用することで、エージェントは専用ノードを実行することなくオンチェーンアクションを実行できます。

@elizaos/plugin-evmでのプロバイダーの実装方法は以下のとおりです:

export class WalletProvider {
    private cache: NodeCache;
    private cacheKey: string = "evm/wallet";
    private currentChain: SupportedChain = "mainnet";
    private CACHE_EXPIRY_SEC = 5;
    chains: Record<string, Chain> = { ...viemChains };
    account: PrivateKeyAccount;
    constructor(
        accountOrPrivateKey: PrivateKeyAccount | 
コピー
0x${string}
,
        private cacheManager: ICacheManager,
        chains?: Record<string, Chain>
    ) {
        this.setAccount(accountOrPrivateKey);
        this.setChains(chains);
        if (chains && Object.keys(chains).length > 0) {
            this.setCurrentChain(Object.keys(chains)[0] as SupportedChain);
        }
        this.cache = new NodeCache({ stdTTL: this.CACHE_EXPIRY_SEC });
    }
    getAddress(): Address {
        return this.account.address;
    }
    getCurrentChain(): Chain {
        return this.chains[this.currentChain];
    }
    getPublicClient(
        chainName: SupportedChain
    ): PublicClient<HttpTransport, Chain, Account | undefined> {
        const transport = this.createHttpTransport(chainName);
        const publicClient = createPublicClient({
            chain: this.chains[chainName],
            transport,
        });
        return publicClient;
    }
    getWalletClient(chainName: SupportedChain): WalletClient {
        const transport = this.createHttpTransport(chainName);
        const walletClient = createWalletClient({
            chain: this.chains[chainName],
            transport,
            account: this.account,
        });
        return walletClient;
    }
    getChainConfigs(chainName: SupportedChain): Chain {
        const chain = viemChains[chainName];
        if (!chain?.id) {
            throw new Error("Invalid chain name");
        }
        return chain;
    }
    async getWalletBalance(): Promise<string | null> {
        const cacheKey = "walletBalance_" + this.currentChain;
        const cachedData = await this.getCachedData<string>(cacheKey);
        if (cachedData) {
            elizaLogger.log(
                "Returning cached wallet balance for chain: " +
                    this.currentChain
            );
            return cachedData;
        }
        try {
            const client = this.getPublicClient(this.currentChain);
            const balance = await client.getBalance({
                address: this.account.address,
            });
            const balanceFormatted = formatUnits(balance, 18);
            this.setCachedData<string>(cacheKey, balanceFormatted);
            elizaLogger.log(
                "Wallet balance cached for chain: ",
                this.currentChain
            );
            return balanceFormatted;
        } catch (error) {
            console.error("Error getting wallet balance:", error);
            return null;
        }
    }
    async getWalletBalanceForChain(
        chainName: SupportedChain
    ): Promise<string | null> {
        try {
            const client = this.getPublicClient(chainName);
            const balance = await client.getBalance({
                address: this.account.address,
            });
            return formatUnits(balance, 18);
        } catch (error) {
            console.error("Error getting wallet balance:", error);
            return null;
        }
    }
    addChain(chain: Record<string, Chain>) {
        this.setChains(chain);
    }  
}
コピー

アクション

アクションはAIエージェントが実行できる具体的な動作を定義し、外部システムとの連携、リクエストの処理、タスクの自動化を可能にします。各アクションは、トランザクションの送信、データの取得、スマートコントラクト呼び出しの実行など、個別の機能を実行するよう設計されており、エージェントが環境内で効率的に動作することを保証します。

@elizaos/plugin-evmでは、アクションによってトークン転送、スワップ、ブロックチェーンインタラクションが促進され、AIエージェントがEVM互換ネットワーク上で直接トランザクションを実行できるようになります。これらのアクションはユーザー入力または事前定義されたロジックによってトリガーされ、ブロックチェーン関連の操作のシームレスな実行を保証します。

@elizaos/plugin-evmでのトークン転送アクションの実装方法は以下のとおりです:

async transfer(params: TransferParams): Promise<Transaction> {
        console.log(
           
コピー
Transferring: ${params.amount} tokens to (${params.toAddress} on ${params.fromChain})

        );
        if (!params.data) {
            params.data = "0x";
        }
        this.walletProvider.switchChain(params.fromChain);
        const walletClient = this.walletProvider.getWalletClient(
            params.fromChain
        );
        try {
            const hash = await walletClient.sendTransaction({
                account: walletClient.account,
                to: params.toAddress,
                value: parseEther(params.amount),
                data: params.data as Hex,
                kzg: {
                    blobToKzgCommitment: function (_: ByteArray): ByteArray {
                        throw new Error("Function not implemented.");
                    },
                    computeBlobKzgProof: function (
                        _blob: ByteArray,
                        _commitment: ByteArray
                    ): ByteArray {
                        throw new Error("Function not implemented.");
                    },
                },
                chain: undefined,
            });
            return {
                hash,
                from: walletClient.account.address,
                to: params.toAddress,
                value: parseEther(params.amount),
                data: params.data as Hex,
            };
        } catch (error) {
            throw new Error(
コピー
Transfer failed: ${error.message}
);
        }
    }
コピー

環境変数、キャラクターファイルの設定、使用するElizaプラグインの指定が完了したので、すべてをまとめてAIエージェントをテストしましょう。

プロジェクトのビルド

pnpm build

キャラクターの実行

pnpm start --character="characters/degen.character.json"

クライアントの起動

pnpm start:client

それでは、エージェントと連携して特定のタスクを実行するよう指示してみましょう。

まとめ

EthereumおよびEVM互換ブロックチェーンと連携するAIエージェントを構築することで、自動化されたインテリジェントなオンチェーンインタラクションの新たな可能性が開かれます。このガイドでは、Characters、Agents、Providers、Actionsの定義を通じて、エージェントがトークンの転送とスワップを自律的に実行できるようにする方法を説明しました。

ElizaOSのモジュラーフレームワークを活用することで、開発者はブロックチェーンネットワークとシームレスに連携するAI搭載のDeFiアシスタント、取引ボット、またはポートフォリオマネージャーを作成できます。基盤が整ったので、その機能の拡張、ロジックの改善、新機能の統合を試みて、オンチェーン自動化をさらに強化してみましょう。

AIによる翻訳です。エラーが含まれている可能性があります。常に情報を確認してください。

翻訳を評価する
  • Kingsley Okonkwo
    Kingsley Okonkwo

    Kingsleyは、認定Ethereumブロックチェーン開発者であり、Consensysでテクニカルライターとして勤務し、開発者ツールを専門としています。Consensys入社以前は、GigsterBraintrustなど複数のプラットフォームでフリーランスのバックエンド開発者として活躍していました。5年にわたるソフトウェア開発経験を持ち、JavaScript(Node.js & React)、GoLang、SQL、Dockerなどのツールに精通しています。Kingsleyは、最新のweb3技術を活用したステップバイステップのチュートリアルやハウツーガイドの作成を得意とし、他の開発者がより優れたdappを構築できるよう支援しています。現在はドバイを拠点とし、余暇にはバスケットボールやサッカーを楽しんでいます。

    すべての記事を読む