HyperCore <> HyperEVM 間の送金
はじめに
スポット資産は HyperCore と HyperEVM の間で送金できます。これらの送金の文脈では、HyperCore 上のスポット資産は Core spot、EVM 上のスポット資産は EVM spot と呼ばれます。スポットデプロイヤーは、自分の Core スポット資産を、EVM にデプロイされた任意の ERC20 コントラクトにリンクできます。Core スポット資産と ERC20 トークンはどちらの順序でもデプロイできます。
HyperCore のネイティブトークンとして、HYPE は ERC20 コントラクトではなく、ネイティブの HyperEVM 残高にリンクされます。
システムアドレス
すべてのトークンは Core 上にシステムアドレスを持ちます。これは最初のバイトが 0x20 で、残りのバイトがすべてゼロのアドレスですが、トークンインデックスのみがビッグエンディアン形式でエンコードされます。例えば、トークンインデックス 200 の場合、システムアドレスは 0x20000000000000000000000000000000000000c8 です。
例外は HYPE で、そのシステムアドレスは 0x2222222222222222222222222222222222222222 です。
HYPE の送金
HYPE は HyperEVM 上のネイティブガストークンであるため、特別なケースです。送金の EVM 側では、HYPE は ERC20 トークンではなくネイティブガストークンとして受け取られます。HyperCore に戻すには、HYPE をトランザクション値として送信できます。EVM の送金アドレス 0x222..2 はシステムコントラクトで、payable の receive() 関数として event Received(address indexed user, uint256 amount) を発行します。ここで user は msg.sender であるため、この実装によりスマートコントラクトと EOA の両方が HYPE を HyperCore に戻すことができます。EVM 側でこのログを発行するには小さなガス代がかかることに注意してください。
Core と EVM 間の送金
トークンがリンクされた後にのみ、sendAsset アクション(またはフロントエンド経由)と、EVM 上では ERC20 transfer を使用して、HyperCore と HyperEVM のスポット間で変換できます。
HyperCore から HyperEVM へのトークン送金は、宛先として対応するシステムアドレスを指定した sendAsset アクション(またはフロントエンド経由)で行えます。トークンは、システムアドレスとしてリンクされたコントラクト上で transfer(recipient, amount) を呼び出すシステムトランザクションによってクレジットされます。ここで recipient は sendAsset アクションの送信者です。
HyperEVM から HyperCore へのトークン送金は、宛先として対応するシステムアドレスを指定した ERC20 transfer で行えます。トークンは、リンクされたコントラクトから発行された Transfer(address from, address to, uint256 value) に基づいて Core にクレジットされます。
Core と EVM のスポット間の正確な代替性を盲目的に想定しないでください。詳細は #caveats を参照してください。
ガス代
HyperEVM から HyperCore への送金にかかるガス代は、既存の残高を持つ HyperEVM 上の他の任意のアドレスへの ERC20 トークンまたは HYPE の同等の送金と同程度です。
HyperCore から HyperEVM への送金には、次の HyperEVM ブロックのベースガスプライスで 200k ガスがかかります。
Core と EVM のスポット資産のリンク
Core スポットと EVM スポットの間の送金が機能するためには、トークンのシステムアドレスがもう一方の側の非システム残高の総量を持っている必要があります。例えば、既存の Core スポット資産用に ERC20 コントラクトをデプロイするには、システムコントラクトが Core スポットの最大供給量に等しい EVM スポット供給量の全体を持つ必要があります。\ \ これが完了したら、スポットデプロイヤーはトークンを EVM にリンクするためのスポットデプロイアクションを送信する必要があります:
/**
* @param token - The token index to link
* @param address - The address of the ERC20 contract on the evm.
* @param evmExtraWeiDecimals - The difference in Wei decimals between Core and EVM spot. E.g. Core PURR has 5 weiDecimals but EVM PURR has 18, so this would be 13. evmExtraWeiDecimals should be in the range [-2, 18] inclusive
*/
interface RequestEvmContract {
type: “requestEvmContract”;
token: number;
Address: address;
evmExtraWeiDecimals: number;
}
このアクションを送信すると、HyperCore はリンクされる保留中の EVM アドレスを保存します。EVM コントラクトのデプロイヤーは、次の 2 つの方法のいずれかで、HyperCore トークンにリンクする意図を検証する必要があります:
- EVM コントラクトが EOA からデプロイされた場合、EVM ユーザーは EVM コントラクトのデプロイに使用された nonce を使ってアクションを送信できます。
- EVM コントラクトが別のコントラクト(例: マルチシグ経由の create2)によってデプロイされた場合、コントラクトの最初のストレージスロットまたは keccak256("HyperCore deployer") のスロットに、ファイナライザーユーザーのアドレスが保存されていなければなりません。
リンクを確定するために、ファイナライザーユーザーは以下のアクションを送信します(これはスポットデプロイアクションの中にネストされないことに注意)。"create" のケースでは EVM デプロイヤーがアクションを送信します。"firstStorageSlot" または "customStorageSlot" のケースでは、ファイナライザーは対応するスロットの値と一致しなければなりません。
/**
* @param input - One of the EVM deployer options above
*/
interface FinalizeEvmContract {
type: “finalizeEvmContract”;
token: number;
input: {"create": {"nonce": number}} | "firstStorageSlot" | "customStorageSlot"};
}
注意事項
現在、システムアドレスが十分な供給量を持っているか、またはコントラクトが有効な ERC20 であるかのチェックはないため、資金を送る際は注意してください。
特に、リンクされたコントラクトは任意のバイトコードを持つ可能性があるため、その実装が正しいことを検証するのが賢明です。EVM 上で transfer 呼び出しが何をするかについての保証はないため、リンクされた EVM コントラクトのソースコードと総残高を必ず検証してください。
EVM コントラクトに追加の Wei 桁がある場合、発行された関連ログの値が丸い数(extraEvmWeiDecimals 個のゼロで終わらない)でない場合、丸くない額はバーンされます(<1 Wei であることが保証されます)。これは HYPE およびその他すべてのスポットトークンに当てはまります。
メインネットの PURR
メインネットの PURR は 0x9b498C3c8A0b8CD8BA1D9851d40D186F1872b44E に以下のコードで ERC20 コントラクトとしてデプロイされています。メインネットでリンクが有効になると、HyperCore の PURR にリンクされます。
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";
contract Purr is ERC20Permit {
constructor() ERC20("Purr", "PURR") ERC20Permit("Purr") {
address initialHolder = 0x2000000000000000000000000000000000000001;
uint256 initialBalance = 600000000;
_mint(initialHolder, initialBalance * 10 ** decimals());
}
}
最後に
EVM に ERC20 トークンをデプロイして Core スポットトークンにリンクするサンプルスクリプトを添付します。
{% file src="/files/ByYbxCDq0BaOoY6akDhN" %}