はじめに

初めまして。 CryptoGamesというブロックチェーンゲーム企業でエンジニアをしている cardene(かるでね) です! スマートコントラクトを書いたり、フロントエンド・バックエンド・インフラと幅広く触れています。

代表的なゲームはクリプトスペルズというブロックチェーンゲームです。

今回は、債券をトークン化して、債券の発行や償還などを効率的の処理できる提案であるERC3475についてまとめていきます!

以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。

概要

このEIPは、ブロックチェーン上で債券をトークン化するための提案です。 従来のトークン規格では、複数の償還データを持つ債券を作成することが難しかったのですが、このEIPによってその問題が解決されます。

償還データとは、債券や証券などの金融商品において、投資家が元本や利息などを受け取るための条件やタイミングを示す情報のことを指します。 債券を発行する際、投資家がいくつかの期間にわたって元本を返還されるか、または利息を受け取るか、あるいはその両方が含まれる場合があります。 これらの条件は償還データとして知られ、債券保有者が将来の収益を予測し、投資判断を行うための重要な情報です。

例えば、特定の日付に利息を支払うタイプの債券では、その利息の支払日や支払額、または元本の一部を返還するタイプの債券では、元本の償還日や金額が償還データとなります。 これらのデータは投資家や市場参加者にとって、債券の価値評価や取引戦略を検討する際に重要な要素となります。

具体的には、各債券の種類を識別するためのクラスIDが導入され、それぞれのクラスには債券の発行条件やその他のデータを表すための「ノンス」と呼ばれる数字が関連付けられます。 このノンスは、uint256という特殊な形式の数値で表されます。 そして、各債券のノンスは、その債券に関する情報や条件を持つことができます。 例えば、債券のメタデータ、供給量(発行数)、償還条件などが含まれます。

この新しい方法によって作成された債券は、発行や償還の条件を効率的にまとめて処理することができます。 これにより、ガスコスト(トランザクション手数料)の削減やユーザーエクスペリエンスの向上が期待されます。 最終的に、この新しい規格から生まれる債券は、二次市場で分割したり交換したりすることができるようになります。

動機

現在のLP(Liquidity Provider)トークンは、簡単なEIP20トークンで、複雑なデータ構造を持っていません。 しかし、より複雑な報酬や償還(返済)の仕組みをブロックチェーン上で管理するためには、新しいトークン規格が必要です。

新しい規格では、以下の特徴が備わっています。

1. 複数のトークンIDをサポート

これにより、異なる種類のトークンを同じ枠組みで取り扱うことができます。 例えば、異なる種類の債務を異なるトークンとして発行できます。

2. オンチェーンのメタデータ

トークンに関連する情報や条件をオンチェーンで保存できます。 これにより、トークンに関する詳細な情報をブロックチェーン上で管理できます。

3. 柔軟なストレージパターン

従来のトークン規格では、特定のデータ構造が必要でしたが、新しい規格では柔軟なデータの保存が可能です。

4. ガス効率が良い

トランザクションの手数料(ガス)を削減するために、効率的な方法でデータを管理します。

また、この新しい規格には以下の利点もあります。

  • このEIPによって、同じ方法で異なる種類の債務を作成できるようになります。
    • これにより、複雑なトークンの作成が容易になります。
  • 第三者のウォレットアプリケーションや取引所も、この規格に準拠したトークンの情報を簡単に読み取ることができます。
    • これにより、トークンの管理や取引がスムーズに行えます。
  • 作成された債券は、トレード可能なユニットとしてまとめて扱うことができます。
    • そして、これらのユニットは二次市場で分割や交換が可能です。

この新しい規格は、複雑な金融商品の管理や取引をより効率的に行うための手段として提供されています。

仕様

定義

Bunk

Bunkとは、特定の条件を満たすために必要なお金や資金を手に入れた後、債券を作成したり、元本を返済したり、債券を取り消したりする機関のことを指します。 一般的には、この役割を担うのは管理アクセスを持つ単一の組織やエンティティです。 この組織は、債券の発行や償還、取り消しといったトランザクションを管理し、債券が正しく運用されることを確保します。 そのため、銀行は債券に関するプール(集積)への管理権限を持っています。

関数

javascript
pragma solidity ^0.8.0;

function transferFrom(address _from, address _to, Transaction[] calldata _transactions) external;

function transferAllowanceFrom(address _from,address _to, Transaction[] calldata _transactions) public ;

function issue(address _to, Transaction[] calldata _transaction) external; 

function redeem(address _from, Transaction[] calldata _transactions) external; 

function burn(address _from, Transaction[] calldata _transactions) external; 

function approve(address _spender, Transaction[] calldata _transactions) external;

function setApprovalFor(address _operator, bool _approved) external returns(bool approved);

function totalSupply(uint256 classId, uint256 nonceId) external view returns (uint256);

function redeemedSupply(uint256 classId, uint256 nonceId) external view returns (uint256);

function activeSupply(uint256 classId, uint256 nonceId) external view returns (uint256);

function burnedSupply(uint256 classId, uint256 nonceId) external view returns (uint256);

function balanceOf(address _account, uint256 classId, uint256 nonceId) external view returns (uint256);

function classMetadata(uint256 metadataId) external view returns (Metadata memory);

function nonceMetadata(uint256 classId, uint256 metadataId) external view returns (Metadata memory);

function classValues(uint256 classId, uint256 metadataId) external view returns (Values memory);

function nonceValues(uint256 classId, uint256 nonceId, uint256 metadataId) external view returns (Values memory);

function getProgress(uint256 classId, uint256 nonceId) external view returns (uint256 progressAchieved, uint256 progressRemaining);

function allowance(address _owner, address _spender, uint256 classId, uint256 nonceId) external returns(uint256);

function isApprovedFor(address _owner, address _operator) external view returns (bool);

transferFrom

概要 トークンの送付を行う関数。

詳細 指定したアドレスから別のアドレスへトークンを送付します。 複数のトランザクションが同時に行われることもあります。 送信元アドレスから送信先アドレスに、指定した債券クラスID、ノンスID、数量のトークンを送信します。

引数

  • _from
    • トークンの送信元アドレス。
  • _to
    • トークンの送信先アドレス。
  • _transactions
    • トランザクションの配列。
    • 各トランザクションは債券クラスID、ノンスID、数量を持つ。

transferAllowanceFrom

概要 特定の承認範囲内でトークンの送付を行う関数。

詳細 承認されたトークンの範囲内で、指定したアドレスから別のアドレスへトークンを送信します。 複数のトランザクションが同時に行われることもあります。 送信元アドレスから送信先アドレスに、指定した債券クラスID、ノンスID、数量のトークンを送信します。

引数

  • _from
    • トークンの送信元アドレス。
  • _to
    • トークンの送信先アドレス。
  • _transactions
    • トランザクションの配列。
    • 各トランザクションは債券クラスID、ノンスID、数量を持つ。

issue

概要 指定したアドレスにトークンを発行する関数。

詳細 特定のアドレスに、指定した債券クラスID、ノンスID、数量のトークンを発行します。 発行は特定のエンティティによって行われる必要があります。 複数のトランザクションが同時に行われることもあります。

引数

  • _to
    • トークンを発行するアドレス。
  • _transactions
    • トランザクションの配列。
    • 各トランザクションは債券クラスID、ノンスID、数量を持つ。

redeem

概要 トークンの償還を許可する関数。

詳細 指定したアドレスからトークンを償還します。 償還は特定の条件を満たした後に行われる必要があります。 償還はBunkや二次市場メーカーコントラクトによってのみ行われるべきです。

引数

  • _from
    • トークンの償還元アドレス。
  • _transactions
    • トランザクションの配列。
    • 各トランザクションは債券クラスID、ノンスID、数量を持つ。

burn

概要 トークンをバーン(0アドレスに送付)する関数。

詳細 指定したアドレスからトークンをバーンします。 バーンは特定の条件を満たした後に行われる必要があります。 バーンはBunkや二次市場メーカーコントラクトによってのみ行われるべきです。

引数

  • _from
    • トークンのバーン元アドレス。
  • _transactions
    • トランザクションの配列。
    • 各トランザクションは債券クラスID、ノンスID、数量を持つ。

approve

概要 特定のアドレスに対するトークンの承認をする関数。

詳細 指定したアドレスに対して、特定の債券クラスID、ノンスID、数量のトークンを承認します。 承認はBunkやアカウントの所有者によってのみ行われます。

引数

  • _spender
    • トークンを送信することを許可するアドレス。
  • _transactions
    • トランザクションの配列。
    • 各トランザクションは債券クラスID、ノンスID、数量を持つ。

setApprovalFor

概要 第三者(オペレータ)が所有者の特定の債券クラスを管理するための承認を有効または無効にする関数。

詳細 指定したアドレスが特定の債券クラスを管理するための承認を有効または無効にします。 承認の条件は内部関数によって定義される必要があり、Bunkやアカウントの所有者によってのみ呼び出すことができます。

引数

  • _operator
    • 承認するオペレータのアドレス。
  • _approved
    • 承認を有効にする場合はtrue、無効にする場合はfalse。

戻り値 承認が成功したかどうか(true または false)。


totalSupply

概要 指定した債券クラスとノンスのトークンの総供給量を返す関数。

詳細 指定した債券クラスとノンスのトークンの総供給量を返します。 この総供給量には、償還済みや無効化されたトークンも含まれます。

引数

  • classId
    • 債券クラスのID。
  • nonceId
    • ノンスのID。

戻り値 トークンの総供給量。


redeemedSupply

概要 指定した債券クラスとノンスのトークンの償還済み供給量を返す関数。

引数

  • classId
    • 債券クラスのID。
  • nonceId
    • ノンスのID。

戻り値 トークンの償還済み供給量。


activeSupply

概要 指定した債券クラスとノンスのアクティブな供給量を返す関数。

詳細 指定した債券クラスとノンスのアクティブな供給量を返します。 アクティブな供給量は償還済みや無効化されていないトークンの供給量です。

引数

  • classId
    • 債券クラスのID。
  • nonceId
    • ノンスのID。

戻り値 アクティブなトークンの供給量。


burnedSupply

概要 指定した債券クラスとノンスの無効化済みトークンの供給量を返す関数。

引数

  • classId
    • 債券クラスのID。
  • nonceId
    • ノンスのID。

戻り値 無効化済みトークンの供給量。


balanceOf

概要 指定したアドレスが保持する特定の債券クラスとノンスのトークン残高を返す関数。

詳細 指定したアドレスが保持する特定の債券クラスとノンスのトークン残高を返します。 これには償還済みのトークンも含まれます。

引数

  • _account
    • トークンの残高を取得するアドレス。
  • classId
    • 債券クラスのID。
  • nonceId
    • ノンスのID。

戻り値 指定したアドレスが保持するトークンの残高。


classMetadata

概要 指定した債券クラスのメタデータを返す関数。

詳細 指定した債券クラスのメタデータを返します。 メタデータはJSON形式で提供され、タイトルやタイプ、説明などが含まれます。

引数

  • metadataId
    • メタデータのインデックスID。

戻り値 指定した債券クラスのメタデータ(JSON形式)。


nonceMetadata

概要 指定した債券クラスとノンスのメタデータを返す関数。

詳細 指定した債券クラスとノンスのメタデータを返します。 メタデータはJSON形式で提供され、タイトルやタイプ、説明などが含まれます。

引数

  • classId
    • 債券クラスのID。
  • `nonceId
    • ノンスのID。
  • metadataId
    • メタデータのインデックスID。

戻り値 指定した債券クラスとノンスのメタデータ(JSON形式)。


classValues

概要 特定の債券クラスの値を返す関数。

詳細 特定の債券クラスの値を返します。 これには文字列や数値、アドレスなどのデータが含まれます。

引数

  • classId
    • 債券クラスのID。
  • metadataId
    • メタデータのインデックスID。

戻り値 指定した債券クラスの値。


nonceValues

概要 特定の債券クラスとノンスの値を返す関数。

詳細 特定の債券クラスとノンスの値を返します。 これには文字列や数値、アドレスなどのデータが含まれます。

引数

  • classId
    • 債券クラスのID。
  • nonceIdノンスのID。
  • metadataIdメタデータのインデックスID。

戻り値 指定した債券クラスとノンスの値。


getProgress

概要 トークンの償還進行状況を取得する関数。

詳細 指定した債券クラスとノンスのトークンの償還進行状況を取得します。 進行状況は、償還条件に基づく進捗と残りのトークン供給量を示します。

引数

  • classId
    • 債券クラスのID。
  • nonceId
    • ノンスのID。

戻り値 トークンの償還進行状況。


allowance

概要 指定したオーナーアドレスが、特定の債券クラスとノンスに関して、指定したスペンダーアドレスがどれだけのトークンを引き出すことができるかを許可する関数。

詳細 オーナーアドレスとスペンダーアドレス、債券クラスID、およびノンスIDを指定して呼び出します。 この関数の呼び出しによって設定されたトークンの許可量は、_amountとして戻り値として返されます。

引数

  • _owner
    • トークンのオーナーとなるアドレス。
  • _spender
    • トークンを引き出すことを許可されるアドレス。
  • classId
    • 債券クラスのID。
  • nonceId
    • ノンスのID。

戻り値 スペンダーアドレスがまだオーナーアドレスから引き出すことができる残高(_amount)。


isApprovedFor

概要 指定したオペレーターアドレスが、特定のオーナーアドレスの債券クラスを管理するために承認されているか取得する関数。

詳細 この関数は、指定したオペレーターアドレスが指定したオーナーアドレスの債券クラスを管理するために承認されているかどうかを確認します。 オーナーアドレスとオペレーターアドレスを指定して呼び出します。 もしもオペレーターアドレスが承認されている場合、trueを、承認されていない場合、falseを返します。

引数

  • _owner
    • オーナーのアドレス。
  • _operator
    • 承認のステータスを確認するオペレーターのアドレス。

戻り値 オペレーターアドレスが特定のオーナーアドレスの債券クラスを管理するために承認されている場合、true、 承認されていない場合、falseを返す。


イベント

javascript
event Issue(address indexed _operator, address indexed _to, Transaction[] _transactions); 

event Redeem(address indexed _operator, address indexed _from, Transaction[] _transactions);

event burn(address _operator, address _owner, Transaction[] _transactions);

event Transfer(address indexed _operator, address indexed _from, address indexed _to, Transaction[] _transactions);

event ApprovalFor(address indexed _owner, address indexed _operator, bool _approved);

Issue

概要 債券が発行された時に発行されるイベント。

詳細 このイベントは、オペレーター(銀行アドレスなど)コントラクトが特定のエンティティに対して債券を発行する際に発行されます。

パラメータ

  • _operator
    • イベントをトリガーしたオペレーターアドレス
  • _to
    • 債券を発行する受取人のアドレス。
  • _transactions
    • 発行するトランザクションの配列。

Redeem

概要 債券が償還された時に発行されるイベント。

パラメータ

  • _operator
    • イベントをトリガーしたオペレーターアドレス。
  • _from
    • 債券を償還する元のアドレス。
  • _transactions
    • 償還するトランザクションの配列。

Burn

概要 債券が破棄(燃やされる)された時に発行されるイベント。

パラメータ

  • _operator
    • イベントをトリガーしたオペレーターアドレス。
  • _owner
    • 債券を破棄するアドレス。
  • _transactions
    • 破棄するトランザクションの配列。

Transfer

概要 債券がアドレス間で移動された時に発行されるイベント。

詳細 このイベントは、オペレーターアドレスからオーナーアドレス(_from)から受け取るアドレス(_to)へ債券が移動された際に発行されます。

引数

  • _operator
    • イベントをトリガーしたオペレーターアドレス。
  • _from
    • 債券を移動する元のアドレス。
  • _to
    • 債券を移動する先のアドレス。
  • _transactions
    • 移動する債券のトランザクションの配列。

ApprovalFor

概要 債券保有者がオペレーターを承認する時に発行されるイベント。

詳細 このイベントは、オーナーアドレスが特定のオペレーターアドレスを債券の移動に承認する際に発行されます。

パラメータ

  • _owner
    • 承認するオーナーアドレス。
  • _operator
    • 承認されるオペレーターアドレス。
  • _approved
    • 承認のステータス(trueまたはfalse)。

メタデータ

債券クラスまたはNonceのメタデータは、以下のタイプで表されるJSONオブジェクトの配列として格納されます。 すべてのメタデータのスキーマはこちらから参照されます。

メタデータは、Nonce(識別子)やクラスの追加情報を定義します。 これらの情報は、フロントエンド(ユーザーインターフェース)がでのデータ管理・理解に使用されます。

Description metadata

json
[
    {
        "title": "defining the title information",
        "_type": "explaining the type of the title information added",
        "description": "little description about the information stored in  the bond",
    }
]

example

json
{
    "title": "localisation",
    "_type": "string",
    "description": "jurisdiction law codes compatibility"
    "values": ["fr ", "de", "ch"]
}
Nonce

メタデータ内の情報を検索するための主要な値は「class」というフィールドです。 以下にそのルールを示します。

  • タイトルは、メタデータの説明に基づいて区別される、英数字です。
    • ただし、特定の管轄によって異なる場合があります。
  • タイトルは空にすることはできません。
  • メタデータの具体例には、債券の地域化情報や管轄の詳細などがあり、これらはmetadata.mdという例の説明ファイルに記載されています。

Nonce metadata

json
[	
	{	
	"title": "maturity",
	"_type": "uint",
	"description": "Lorem ipsum...",
	"values": [0, 0, 0]
	}
]
クラスメタデータ

この構造は、クラスに関する詳細情報(シンボル、リスク情報など)を定義します。 詳細な例は、クラスメタデータセクションに説明があります。

Class metadata

json
[ 
	{	
	"title": "symbol",
	"_type": "string",
	"description": "Lorem ipsum...",
	"values": ["Class symbol 1", "Class symbol 2", "Class symbol 3"],
	},
	{	
	"title": "issuer",
	"_type": "string",
	"description": "Lorem ipsum...",
	"values": ["Issuer name 1", "Issuer name 2", "Issuer name 3"],
	},

	{	
	"title": "issuer_address",
	"_type": "address",
	"description": "Lorem ipsum...",
	"values":["Address 1.", "Address 2", "Address 3"]
	},

	{	
	"title": "class_type",
	"_type": "string",
	"description": "Lorem ipsum...",
	"values": ["Class Type 1", "Class Type 2", "Class Type 3"]
	},

	{	
	"title": "token_address",
	"_type": "address",
	"description": "Lorem ipsum...",
	"values":["Address 1.", "Address 2", "Address 3"]
	},

	{	
	"title": "period",
	"_type": "uint",
	"description": "Lorem ipsum...",
	"values": [0, 0, 0]
	}
]
データのデコード

対応するフロントエンドがメタデータを理解するために、ClassMetadataやNonceMetadataという関数を使用して、債券の情報を解読する必要があります。

これは、ClassMetadataやNonceMetadataという関数のインターフェースをオーバーライドして、JSONオブジェクトとして格納された情報を読み取るためのキー(インデックス)を定義することによって行われます。

例:

json
{
 "title": "symbol",
 "_type": "string",
 "description": "以下の形式で一意の識別子名を定義します:(シンボル、債券の種類、満期までの月数)",
 "values": ["クラス名1", "クラス名2", "DBIT Fix 6M"]
}

上記の例では、与えられたクラスIDを使ってシンボルの値を取得するために、クラスIDをキーとしてvaluesからシンボル値を取得し、詳細を取得するのに利用できます。

補足

メタデータ構造

通常、債券のクラスや発行情報(Nonce)の詳細は外部に保存されることがありますが、このシステムではそれらの詳細情報を内部の構造体に格納します。 ここでのクラスは異なる債券の種類を表し、Nonceは異なる発行期間を表します。 同じクラスに属するNonceは同じメタデータを共有します。 一方、Nonceは代替不可能(Non-Fungible)です。 それぞれのNonceは異なるセットのメタデータを格納できます。 そのため、債券の所有者が変わる際には、全てのメタデータが新しい所有者に引き継がれます。

javascript
struct Values{
    string stringValue;
    uint uintValue;
    address addressValue;
    bool boolValue;
    bytes bytesValue;
}
javascript
struct Metadata {
    string title;
    string _type;
    string description;
}

バッチ関数

このEIPでは、バッチ操作という機能が導入されています。 これにより、複数の異なる種類の債券とそれに関連するメタデータを、一度にまとめて新しいアドレスに移動することができます。 これらの操作は、単一のトランザクション内で即座に処理されます。 トランザクションが完了すると、新しい所有者は各債券の額面価格を請求できる権利を持ちます。 この仕組みは、債券を効率的に「パッケージング」することができ、特に二次市場などでの取引に非常に有用です。

Transaction構造体は、このバッチ操作をサポートするために使用されます。

javascript
 struct Transaction {
 uint256 classId;
 uint256 nonceId;
 uint256 _amount;
 }
  • classId
    • 債券の種類を識別するための番号。
    • 異なる種類の債券を区別するために使用されます。
  • nonceId
    • 与えられた債券クラス内での発行条件を特定するための番号。
    • 同じクラス内でも、異なる発行条件を持つ債券を区別するのに使用されます。
  • _amount
    • このフィールドに指定された金額の債券が移動の対象。
    • 所有者がこの金額の債券を移動することが許可されます。

これにより、一度のトランザクションで複数の債券とそれに関連する情報をまとめて移動できます。 トランザクションが完了すると、新しい所有者はこれらの債券の所有権を取得し、各債券の額面価格を請求することができます。 この仕組みは、債券を効率的に管理し、取引を簡素化するのに役立ちます。

AMMの最適化

このEIP(イーサリアム改善提案)におけるユースケースとして、AMM(Automated Market Maker)の最適化が挙げられます。 AMMは、トークンの取引を自動化する仕組みで、初期バージョンでは異なるトークンのペアを管理するために独立したスマートコントラクトとEIP20LPトークンを使用します。 しかし、この方法では1つのプール内の総流動性が減少し、無駄なガス消費やスリッページが発生する可能性があります。

このEIPを使用することで、債券の種類(Class)と発行のタイミング(Nonce)に対応する流動性を持つデータ構造を作成できます。 これにより、複数のトークンペアを含む大きな流動性プールを効率的に構築できるようになります。 具体的には、債券の種類と発行タイミングを知ることで、特定のトークンペアの所有者がプール内で持つ流動性を割合として表現できます。 実際に、EIP20LPトークンはプールファクトリーコントラクト内の専用スマートコントラクトで定義され、1つの債券として集約され、1つのプールに統合されます。

この標準の名前「abstract storage bond」は、外部のストレージを必要とせずに、すべての仕様(メタデータ、値、トランザクションなど)を保存できる能力に由来しています。 これにより、効率的なプールの構築と管理が可能となります。

例えば、3つの異なる種類の債券(A、B、C)があり、それぞれ異なる発行タイミング(Nonce)を持っています。 各債券はそれぞれ異なるトークンペアとして取引されます。

従来のアプローチでは、債券A、B、Cそれぞれに対して個別のプールが作成され、それぞれのプールでトークンの交換が行われていました。 しかし、それぞれのプールには総流動性が分散され、効率的な取引が難しい場合があります。

しかし、このEIPの標準を使用すると、新しい方法でプールを構築できます 各債券の種類と発行タイミングに対応するデータ構造を作成し、1つの大きな流動性プールにまとめます。

具体的には、債券A、B、CそれぞれのClassとNonceに対応するデータ構造がプール内に存在します。 各債券の所有者は、自身が持つ債券の種類と発行タイミングを知ることで、プール内での流動性を割合として表現できます。 これにより、例えば債券Aの所有者はプール内で債券Aの流動性の割合を保持し、債券BやCにも同様に対応する所有者が流動性を保持することができます。

さらに、EIP20LPトークンは、各債券の種類と発行タイミングに対応する専用スマートコントラクトで定義され、1つの債券として集約されます。 つまり、債券A、B、CそれぞれのLPトークンが1つの大きなプールに統合され、トークンの交換が効率的に行えるようになります。

このアプローチにより、異なる種類の債券を効率的に1つの大きなプールで取引できるようになります。 総流動性が最適化され、取引がスムーズに行える環境が実現します。

互換性

このEIPは後方互換性があります。 つまり、既存のスマートコントラクトやウォレットもこのEIPのインターフェースを使って、新しい機能を追加できるということです。 これは、債券の発行者や受取人にとっても適用されます。 また、クライアント側のEOAウォレットも、債券のissue()やredeem()といった関数の実行に署名できれば、この標準との互換性が確保されます。

既存のEIP20トークンコントラクトは、既存の機能を維持しながら、このEIPの標準インターフェースを持つ銀行コントラクトにmint権限を委任することで、新たに債券を発行できます。 これにより、既存のトークンを債券として扱うことができます。

さらに、債券のライフサイクル全体にわたる重要なアクション(例えば、「Issue」「Redeem」「Transfer」関数)については、トランザクションの情報を索引付けするためにイベントが必要です。 このEIPの仕様書内で定義されているイベントは、それぞれのアクションが実行された際に発行される必要があります。

なお、この標準のインターフェースはEIP20やEIP721、EIP1155とも互換性があります。 これは、既存のトークンやアセットと統合しやすくする一方で、新しい債券の概念を取り入れることも可能です。

ただし、債券の読み取りや将来のアップグレードのニーズを考慮して、別途銀行コントラクトを作成することを推奨します。 これにより、債券の管理や新機能の追加がスムーズに行えるようになります。

最後に、このEIPは受け入れ可能な担保として、EIP20のような代替可能なトークン、EIP721やEIP1155のような非代替可能なトークン、またはこのEIPで表現される他の債券の形式を受け入れることができます。 つまり、さまざまな種類の資産を組み合わせて債券をサポートできる柔軟性があります。

参考実装

以下に格納しています。

セキュリティ考慮事項

このEIPにおいてセキュリティを確保するためのポイントを説明します。

setApprovalFor関数

この関数は、指定した _operatorAddress にトークン操作権限を与えます。 オペレーターは債券のtransfer、burn、redeemなどのアクションを実行する権限を持ちます。 ただし、この関数を使用する時には、オペレーターに与える権限の範囲を適切に制御することが重要です。 不必要な権限を与えることなく、必要な操作のみを許可するように心がけましょう。

一時的なallowanceについて

オーナーが特定のアドレスに特定の債券(classId、bondsId)に対する一時的なallowanceを提供したい場合、approve() 関数を使用することが推奨されています。 これにより、必要な債券に対して限定的な承認を与えることができます。 これは、セキュリティを強化し、不正なアクセスを防ぐための方法です。

イベントの発行

トランザクションのライフサイクル中(issue、redeem、transferFrom関数など)、仕様セクションで指定されているイベントは、それらのトランザクションが行われた際に必ず発行される必要があります。 これにより、イベントを監視してアクションをトラッキングし、セキュリティを確保することができます。

互換性と銀行コントラクト

既存のEIP20トークンコントラクトは、このEIPのインターフェースを備えた銀行コントラクトにmint権限を委任することで、債券の発行が可能です。 これにより、既存のトークンとの互換性を確保しつつ、新たな機能を導入することができます。

セキュリティの観点から、権限の適切な制御とイベントの正確な発行が重要です。 これにより、ユーザーの資産やデータを保護し、システム全体の信頼性を高めることができます。

引用

Yu Liu (@yuliu-debond), Varun Deshpande (@dr-chain), Cedric Ngakam (@drikssy), Dhruv Malik (@dhruvmalik007), Samuel Gwlanold Edoumou (@Edoumou), Toufic Batrice (@toufic0710), "ERC-3475: Abstract Storage Bonds," Ethereum Improvement Proposals, no. 3475, April 2021. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-3475.

最後に

今回は「債券をトークン化して、債券の発行や償還などを効率的の処理できる提案であるERC3475」についてまとめてきました! いかがだったでしょうか?

質問などがある方は以下のTwitterのDMなどからお気軽に質問してください!