diff --git a/.gitbook/cn/developers-evm/add-injective-to-your-dapp.mdx b/.gitbook/cn/developers-evm/add-injective-to-your-dapp.mdx new file mode 100644 index 0000000..48fed5d --- /dev/null +++ b/.gitbook/cn/developers-evm/add-injective-to-your-dapp.mdx @@ -0,0 +1,65 @@ +--- +title: 将 Injective 添加到你的 dApp +--- + +# 将 Injective 添加到你的 dApp + +让你的用户只需一键即可连接到 Injective 网络。 + +使用下面的代码片段向你的 dApp 添加"添加 Injective 网络"按钮,让用户可以轻松地将 Injective 添加到 MetaMask 或任何 EVM 兼容钱包。 + +1. 将代码片段复制并粘贴到你的前端代码库中。 +2. 将 `addInjectiveNetwork` 函数连接到你首选的 UI 按钮。 +3. 就是这样——你的用户现在可以在几秒钟内将 Injective 添加到他们的钱包 + +```tsx +// 网络配置 +const INJECTIVE_MAINNET_CONFIG = { + chainId: '0x6f0', // 十进制 1776 + chainName: 'Injective', + rpcUrls: ['https://evm-rpc.injective.network'], + nativeCurrency: { + name: 'Injective', + symbol: 'INJ', + decimals: 18 + }, + blockExplorerUrls: ['https://explorer.injective.network'] +}; + +async function addInjectiveNetwork() { + // 检查是否安装了 MetaMask 或其他 Web3 钱包 + if (!window.ethereum) { + alert('Please install MetaMask or another Web3 wallet!'); + return; + } + + try { + // 首先,尝试切换到 Injective 网络 + await window.ethereum.request({ + method: 'wallet_switchEthereumChain', + params: [{ chainId: INJECTIVE_MAINNET_CONFIG.chainId }], + }); + + console.log('Switched to Injective network successfully!'); + } catch (switchError) { + // 错误代码 4902 表示网络尚未添加 + if (switchError.code === 4902) { + try { + // 添加 Injective 网络 + await window.ethereum.request({ + method: 'wallet_addEthereumChain', + params: [INJECTIVE_MAINNET_CONFIG], + }); + + console.log('Injective network added successfully!'); + } catch (addError) { + console.error('Failed to add Injective network:', addError); + alert('Failed to add Injective network. Please try again.'); + } + } else { + console.error('Failed to switch network:', switchError); + alert('Failed to switch to Injective network.'); + } + } +} +``` diff --git a/.gitbook/cn/developers-evm/bank-precompile.mdx b/.gitbook/cn/developers-evm/bank-precompile.mdx new file mode 100644 index 0000000..5662356 --- /dev/null +++ b/.gitbook/cn/developers-evm/bank-precompile.mdx @@ -0,0 +1,50 @@ +--- +title: Bank Precompile +--- + +# Bank Precompile + +Bank Precompile 是一个位于固定地址 `0x0000000000000000000000000000000000000064` 的系统智能合约。 + +它为 EVM 开发者提供了一种高效且原生的方式来直接与 Injective 的 **bank 模块**(`x/bank`)交互。这有效地将 ERC-20 token 带到链上。任何使用 Bank precompile 的 ERC-20 合约将在链上表示为 `erc20:0x...` denom。从技术上讲,这意味着 token 仅存在于链上,EVM 提供链状态的视图而不是维护单独的副本。与传统桥接不同,传统桥接需要用户操作来切换两个 token 版本,Bank precompile 为使用链上 bank denom 或 ERC-20 `transfer()` 方法的任何转账提供实时、双环境反映。 + +一系列由 Bank precompile 支持的 ERC-20 实现,以及 precompile 接口和抽象合约,可在 [Injective 的 Solidity 合约仓库](https://github.com/InjectiveLabs/solidity-contracts) 中找到。关键合约包括: + +* **Bank.sol** – precompile 接口 +* **BankERC20.sol** – 由 Bank precompile 支持的抽象 ERC20 实现 +* **FixedSupplyBankERC20.sol** – 固定供应量的去中心化 ERC20(无所有者,无铸造或销毁) +* **MintBurnBankERC20.sol** – 具有授权铸造和销毁 token 的所有者的 ERC20 + +这些实现基于 OpenZeppelin 的 ERC20 合约。开发者可以自由创建使用 Bank precompile 的自定义 ERC20 合约。 + +## ERC20 合约部署 + +**ℹ️ 注意:** + +为防止 denom 垃圾信息,通过 ERC20 模块部署 ERC20 合约是**付费操作**,需要 **1 INJ** 的部署费用。确保你的 ERC20 合约部署交易包含此金额,否则操作将被拒绝。 + +## Bank Precompile 接口 + +```solidity +interface IBankModule { + function mint(address,uint256) external payable returns (bool); + function balanceOf(address,address) external view returns (uint256); + function burn(address,uint256) external payable returns (bool); + function transfer(address,address,uint256) external payable returns (bool); + function totalSupply(address) external view returns (uint256); + function metadata(address) external view returns (string memory,string memory,uint8); + function setMetadata(string memory,string memory,uint8) external payable returns (bool); +} +``` + +## 示例 + +[Wrapped INJ (wINJ)](/cn/developers-evm/wrapped-inj#is-winj-the-same-as-weth "wINJ 与 wETH 相同吗?") +使用 Bank EVM precompile 来实现 +[MultiVM Token Standard (MTS)](/cn/developers-evm/multivm-token-standard)。 + +## 开始构建 + +我们准备了一些演示,展示如何使用 Bank、Exchange 和 Staking precompiles 构建合约。这些示例还演示了如何使用最常见的 Ethereum 开发框架 **Foundry** 与 Injective EVM 交互。 + +在[这里](https://github.com/InjectiveLabs/solidity-contracts/tree/master/demos/erc20)查看 bank precompile 演示并按照相应的 README 操作。 diff --git a/.gitbook/cn/developers-evm/dapps/connect-with-metamask.mdx b/.gitbook/cn/developers-evm/dapps/connect-with-metamask.mdx new file mode 100644 index 0000000..523a5a4 --- /dev/null +++ b/.gitbook/cn/developers-evm/dapps/connect-with-metamask.mdx @@ -0,0 +1,291 @@ +--- +title: 使用 MetaMask 连接 +--- + +## 将 MetaMask 连接到 Injective EVM Testnet + +MetaMask 是一个浏览器钱包扩展,可让你连接到任何 EVM 兼容网络,包括 **Injective EVM**。 + +### 如何安装 MetaMask + +从 [MetaMask 下载页面](https://metamask.io/download) 安装官方 MetaMask 扩展。 + +### 将 Injective EVM Testnet 添加到 MetaMask + +1. 点击浏览器中的 **MetaMask 图标** 并解锁你的钱包。 +2. 点击顶部的**网络选择器**(默认是 _"Ethereum Mainnet"_)。 +3. 选择 **"Add Network"** 或 **"Add a network manually"** 打开自定义网络表单。 + +#### Injective EVM Testnet 参数 + +填写以下详细信息: + +```json +Network Name: Injective EVM Testnet +Chain ID: 1439 +RPC URL: https://k8s.testnet.json-rpc.injective.network/ +Currency Symbol: INJ +Block Explorer URL: https://testnet.blockscout.injective.network/blocks +``` + +> _注意:Block Explorer URL 是可选的,由 BlockScout 提供支持。_ + +### 切换到 Injective EVM Testnet + +添加网络后,使用网络选择器切换到 **Injective EVM Testnet**。 + +### 为你的钱包充值(可选) + +需要 Testnet INJ?访问 [Injective Testnet faucet](https://testnet.faucet.injective.network)。 + +资金将在包含在 Testnet 区块后显示。 + +*** + +### 设置完成! + +MetaMask 现在已连接到 **Injective EVM Testnet**。你可以: + +* 使用 **Foundry**、**Hardhat** 或 **Remix** 等工具部署智能合约。 +* 与 Testnet dApp 和合约交互。 +* 通过 Blockscout 浏览器检查交易。 + +> **提示:** 始终仔细检查 RPC URL 和 Chain ID - 准确性对于避免配置错误至关重要。 + +*** + +### 通过 `ethers.js` 连接 MetaMask + +你也可以使用 [`ethers`](https://docs.ethers.org/) 以编程方式连接 MetaMask。 + +#### 示例代码 + +```ts +import { ethers } from 'ethers'; + +export const INJECTIVE_EVM_PARAMS = { + chainId: '0x59f', // 1439 的十六进制 + chainName: 'Injective EVM', + rpcUrls: ['https://k8s.testnet.json-rpc.injective.network/'], + nativeCurrency: { + name: 'Injective', + symbol: 'INJ', + decimals: 18, + }, + blockExplorerUrls: ['https://testnet.blockscout.injective.network/blocks'], +}; + +export async function connectMetaMask() { + if (typeof window.ethereum === 'undefined') { + alert('MetaMask not installed!'); + return; + } + + const provider = new ethers.providers.Web3Provider(window.ethereum); + + try { + await window.ethereum.request({ + method: 'wallet_addEthereumChain', + params: [INJECTIVE_EVM_PARAMS], + }); + + await provider.send('eth_requestAccounts', []); + const signer = provider.getSigner(); + const address = await signer.getAddress(); + + console.log('Connected address:', address); + return { provider, signer, address }; + } catch (err) { + console.error('MetaMask connection failed:', err); + } +} +``` + +### 使用 `ethers.js` 与智能合约交互 + +Counter 合约 ABI 示例代码: + +```tsx +// abi/counterAbi.ts +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "reason", + "type": "string" + } + ], + "name": "UserRevert", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newValue", + "type": "uint256" + } + ], + "name": "ValueSet", + "type": "event" + }, + { + "inputs": [], + "name": "increment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "number", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newNumber", + "type": "uint256" + } + ], + "name": "setNumber", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "reason", + "type": "string" + } + ], + "name": "userRevert", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] +``` + +```javascript +import { ethers } from 'ethers' +import { counterAbi } from './abi/counterAbi' +import { INJECTIVE_EVM_PARAMS } from './config' // 从单独的文件 + +// 替换为你部署的合约地址 +const contractAddress = '0xYourContractAddressHere' + +async function connectAndInteract() { + if (!window.ethereum) { + alert('MetaMask is not installed!') + return + } + + // 请求将 Injective EVM 网络添加到 MetaMask + await window.ethereum.request({ + method: 'wallet_addEthereumChain', + params: [ + { + chainId: INJECTIVE_EVM_PARAMS.chainHex, + chainName: INJECTIVE_EVM_PARAMS.chainName, + rpcUrls: [INJECTIVE_EVM_PARAMS.rpcUrl], + nativeCurrency: INJECTIVE_EVM_PARAMS.nativeCurrency, + blockExplorerUrls: [INJECTIVE_EVM_PARAMS.blockExplorer], + }, + ], + }) + + const provider = new ethers.providers.Web3Provider(window.ethereum) + await provider.send('eth_requestAccounts', []) + const signer = provider.getSigner() + const userAddress = await signer.getAddress() + console.log('Connected as:', userAddress) + + // 合约实例 + const contract = new ethers.Contract(contractAddress, counterAbi, signer) + + // 发送交易以增加计数 + const tx = await contract.increment() + console.log('Transaction sent:', tx.hash) + + const receipt = await tx.wait() + console.log('Transaction mined in block:', receipt.blockNumber) +} + +connectAndInteract().catch(console.error) +``` + +### 使用 `viem` 与智能合约交互 + +示例代码 + +```javascript +import { counterAbi } from './abi/counterAbi' +import { INJECTIVE_EVM_PARAMS } from './config' +import { createPublicClient, http } from 'viem' +import { createWalletClient, custom, defineChain, formatEther } from 'viem' + +// 替换为你部署的合约地址 +const contractAddress = '0xYourContractAddressHere' + +async function connectAndInteract() { + if (typeof window === 'undefined' || typeof window.ethereum === 'undefined') { + alert('MetaMask is not installed!') + return + } + + const client = createWalletClient({ + chain: INJECTIVE_EVM_PARAMS, + transport: custom(window.ethereum), + }) + + // 创建 PublicClient 用于读取合约状态 + const publicClient = createPublicClient({ + chain: injectiveEvm, + transport: http(), + }) + + const [account] = await client.requestAddresses() + console.log('Connected account:', account) + + // 使用 wallet client 发送交易以增加计数 + const hash = await client.writeContract({ + address: contractAddress, + abi: counterAbi, + functionName: 'increment', + account, + }) + + console.log('Transaction sent with hash:', hash) +} + +connectAndInteract().catch(console.error) +``` diff --git a/.gitbook/cn/developers-evm/dapps/connect-with-walletconnect.mdx b/.gitbook/cn/developers-evm/dapps/connect-with-walletconnect.mdx new file mode 100644 index 0000000..c4d3e9c --- /dev/null +++ b/.gitbook/cn/developers-evm/dapps/connect-with-walletconnect.mdx @@ -0,0 +1,118 @@ +--- +title: 使用 WalletConnect 连接 +--- + +WalletConnect 是一个开源、链无关的协议,可安全地连接钱包和 Web3 应用。它使用桥接服务器中继加密消息,允许用户通过扫描二维码或深度链接进行连接,而无需暴露私钥。 + +### WalletConnect 集成步骤 + +#### 前置条件 + +在 [WalletConnect Cloud](https://cloud.walletconnect.com) 注册并获取 **project ID**。 + +*** + +#### 安装依赖 + +```bash +npm install ethers wagmi viem @walletconnect/ethereum-provider +``` + +设置 Injective EVM 网络配置 + +```javascript +// lib/injectiveChain.ts +import { defineChain } from 'viem' + +export const injectiveEvm = defineChain({ + id: 1439, + name: 'Injective EVM', + nativeCurrency: { + name: 'INJ', + symbol: 'INJ', + decimals: 18, + }, + rpcUrls: { + default: { http: ['https://k8s.testnet.json-rpc.injective.network'] }, + }, + blockExplorers: { + default: { name: 'InjectiveScan', url: 'https://testnet.blockscout.injective.network/blocks' }, + }, +}) +``` + +设置 Wagmi + WalletConnect + +```javascript + // lib/wagmi.ts +import { walletConnect } from '@wagmi/connectors' +import { createConfig, http } from '@wagmi/core' +import { injectiveEvm } from './injectiveChain' + +export const wagmiConfig = createConfig({ + chains: [injectiveEvm], + connectors: [ + walletConnect({ + projectId: 'your-walletconnect-project-id', // 来自 WalletConnect Cloud + showQrModal: true, + }), + ], + transports: { + [injectiveEvm.id]: http(injectiveEvm.rpcUrls.default.http[0]), + }, +}) + +``` + +集成到你的项目 + +```javascript +'use client' + +import Image from 'next/image' +import { wagmiConfig } from './providers' +import { useConnect, useAccount, WagmiProvider } from 'wagmi' +import { QueryClientProvider, QueryClient } from '@tanstack/react-query' + +export const queryClient = new QueryClient() + +function WalletConnector() { + const { connectors, connect, isPending } = useConnect() + const { address, isConnected } = useAccount() + const wcConnector = connectors.find(c => c.id === 'walletConnect') + + return ( +
+ {isConnected ? ( +

Connected to {address}

+ ) : ( + + )} +
+ ) +} + +export default function Home() { + return ( + + + + + + ) +} + +``` + +*** + +更多信息 + +* WalletConnect 文档: [https://docs.walletconnect.com](https://docs.walletconnect.com) +* WalletConnect 官方示例: [https://github.com/WalletConnect/web-examples](https://github.com/WalletConnect/web-examples) diff --git a/.gitbook/cn/developers-evm/dapps/index.mdx b/.gitbook/cn/developers-evm/dapps/index.mdx new file mode 100644 index 0000000..3fa0ad7 --- /dev/null +++ b/.gitbook/cn/developers-evm/dapps/index.mdx @@ -0,0 +1,16 @@ +--- +description: 使用 MetaMask 或 WalletConnect 连接你的钱包 +title: 你的第一个 EVM dApp +--- + +dApp 是与区块链交互的前端应用, +通常与智能合约交互。 + +请先查看[你的第一个 EVM 智能合约](/cn/developers-evm/smart-contracts/)! + +以下指南向你展示如何使用不同的 EVM 钱包和库进行连接。 + +## 指南 + +* [使用 MetaMask 连接](/cn/developers-evm/dapps/connect-with-metamask/) +* [使用 WalletConnect 连接](/cn/developers-evm/dapps/connect-with-walletconnect/) diff --git a/.gitbook/cn/developers-evm/erc20-module.mdx b/.gitbook/cn/developers-evm/erc20-module.mdx new file mode 100644 index 0000000..dd14d35 --- /dev/null +++ b/.gitbook/cn/developers-evm/erc20-module.mdx @@ -0,0 +1,21 @@ +--- +title: ERC20 Module +--- + +### ERC20 Module + +ERC20 模块使**现有的** bank denom(例如 IBC 桥接的 token、USDC、tokenfactory 和 Peggy)能够与 Injective EVM 集成。它在其存储中维护 token 对之间的映射,创建 ERC20 token 与其对应 bank denom 之间的关联。当为现有 bank denom 生成新的 token 对时,该模块部署一个与 Bank precompile 交互的 ERC20 合约,然后引用存储映射以将 ERC20 地址与相应的 bank denom 对齐。此模块有几个基本用途: + +1. **存储**:在 bank denom ↔ ERC20 地址之间映射 +2. **新消息类型**:使用户能够通过发出链消息来建立新的 token 对映射 + +#### 创建新的 Token 对 + +目前,三种类型的 bank denom 可以有关联的 token 对,每种都有特定的规则: + +* **Tokenfactory (`factory/...`)**\ + 只有 denom 管理员或治理可以创建 token 对。发送者可以指定现有的 ERC20 合约地址作为自定义实现。如果省略,将部署 `MintBurnBankERC20.sol` 的新实例,以 `msg.sender` 作为所有者,允许通过合约铸造和销毁。 +* **IBC (`ibc/...`)**\ + 任何用户都可以通过创建 token 对将 IBC denom 集成到 EVM 中,但没有自定义 ERC20 地址的选项。这些将始终部署一个新的、无所有者的 `FixedSupplyBankERC20.sol` 实例。 +* **Peggy (`peggy0x...`)**\ + 任何用户都可以通过创建 token 对将 Peggy denom 集成到 EVM 中,但没有自定义 ERC20 地址的选项。这些将始终部署一个新的、无所有者的 `FixedSupplyBankERC20.sol` 实例。 diff --git a/.gitbook/cn/developers-evm/evm-equivalence.mdx b/.gitbook/cn/developers-evm/evm-equivalence.mdx new file mode 100644 index 0000000..6d242f2 --- /dev/null +++ b/.gitbook/cn/developers-evm/evm-equivalence.mdx @@ -0,0 +1,42 @@ +--- +description: 了解 Injective 上的 EVM 等效性 +title: EVM 等效性 +--- + +## Injective EVM vs. Ethereum Mainnet + +Injective 的原生 EVM 是一个完全嵌入的执行环境,已集成到链的核心架构中。它被设计为在开发体验方面与 Ethereum 1:1 等效。 + +Injective 上的原生 EVM 支持最新版本的 `geth`,确保开发者可以访问最新的功能、工具、安全补丁和改进。此外,Injective 的 EVM 增强了性能并扩展了功能,授予访问 Injective 复杂金融基础设施的权限,这超出了 Ethereum 上可用的功能。 + +## 交易的 Gas 费用估算 + +| 链 | Gas Price 范围 | Token 价格 | 创建 ERC-4337 账户 | 简单转账 | ERC-20 转账 | +| --- | --- | --- | --- | --- | --- | +| Ethereum¹ | 30.5 ± 10.6 gwei | $3000 | $35.25 ± $12.25 | $1.9215 ± $0.6678 | $5.9475 ± $2.067 | +| Polygon² | 224 ± 108 gwei | $0.4 | $0.0345 ± $0.0166 | $0.0018 ± $0.0009 | $0.0058 ± $0.0028 | +| Optimism³ | 0.30 ± 0.15 gwei | $3000 | $0.3467 ± $0.1733 | $0.0189 ± $0.0094 | $0.0585 ± $0.0292 | +| Avalanche⁴ | 36.4 ± 4.5 nAVAX | $28 | $0.3926 ± $0.0485 | $0.0214 ± $0.0026 | $0.0662 ± $0.0081 | +| BnB Smart Chain⁵ | 7.05 ± 0.53 gwei | $600 | $1.6296 ± $0.1225 | $0.0888 ± $0.0066 | $0.2749 ± $0.0206 | +| Sei⁶ | 0.02 usei | $0.40 | $0.0030 | $0.00017 | $0.0005 | +| Injective⁷ | 0.16 nINJ | $23 | $0.0014 | $0.00008 | $0.0002 | + +### 注意:每个操作的 Gas + +* 创建 ERC-4337 账户: `385266` +* 简单转账: `21000` +* ERC-20 Token 转账: `65000` + +### Gas Price 来源 + +1. [Ethereum Gas Price 来源](https://etherscan.io/chart/gasprice) ↩︎ +2. [Polygon Gas Price 来源](https://polygonscan.com/chart/gasprice) ↩︎ +3. [Optimism Gas Price 来源](https://optimistic.etherscan.io/chart/gasprice) ↩︎ +4. [Avalanche Gas Price 来源](https://snowtrace.io/insight/leaderboard/gas-tracker) ↩︎ +5. [BnB Smart Chain Gas Price 来源](https://bscscan.com/chart/gasprice) ↩︎ +6. [Sei Gas Prices 配置](https://github.com/sei-protocol/chain-registry/blob/main/gas.json) ↩︎ +7. [Injective 推出 Gas 压缩](https://injective.com/blog/injective-unveils-fee-reductions-with-gas-compression/) ↩︎ + +## EIP-1559 配置 + +即将推出。 diff --git a/.gitbook/cn/developers-evm/evm-integrations-cheat-sheet.mdx b/.gitbook/cn/developers-evm/evm-integrations-cheat-sheet.mdx new file mode 100644 index 0000000..742a44f --- /dev/null +++ b/.gitbook/cn/developers-evm/evm-integrations-cheat-sheet.mdx @@ -0,0 +1,132 @@ +--- +title: "EVM 集成速查表" +description: 想在 Injective 的 EVM Mainnet 上构建生产应用?这里有便捷的参考资料帮助你快速完成集成。适用于全新部署和跨链部署。 +--- + +# 网络配置 + +- Chain ID: `1776` + +参考: [EVM 网络信息 | Injective | Docs](/cn/developers-evm/network-information#injective-evm-mainnet) + + +**不要**使用 inEVM,因为它已被**弃用**。 + + +# 浏览器 + +- [https://blockscout.injective.network/](https://blockscout.injective.network/) → 只能查看 EVM 交易 +- [https://injscan.com/](https://injscan.com/) → 可以查看 EVM 和 Cosmos 交易 + +参考: [EVM 网络信息 | Injective | Docs](/cn/developers-evm/network-information#injective-evm-mainnet) + +# RPC Endpoints + +- 推荐给集成合作伙伴 + - 可根据应用需求定制 + - 可定制速率限制,历史数据查询无截止 + - 免费增值/付费选项 + - 如何连接: + - QuickNode: [Injective RPC Node Endpoints, APIs & Tools | QuickNode](https://www.quicknode.com/chains/inj) + - Thirdweb: [Injective EVM](https://thirdweb.com/injective) +- 不推荐给集成合作伙伴 + - 不可根据应用需求定制 + - 严格的速率限制,历史数据查询有截止 + - 免费选项 + - 如何连接: + - JSON-RPC Endpoint: `https://sentry.evm-rpc.injective.network/` + - WS Endpoint: `wss://sentry.evm-ws.injective.network` + +参考: [EVM 网络信息 | Injective | Docs](/cn/developers-evm/network-information#injective-evm-mainnet) + + +**不要**使用 inEVM,因为它已被**弃用**。 + + +# 合约地址 + +| | | | +|---|---|---| +|USDT|MTS USDT|`0x88f7F2b685F9692caf8c478f5BADF09eE9B1Cc13`| +|wETH|wrapped ETH|`0x83A15000b753AC0EeE06D2Cb41a69e76D0D5c7F7`| +|wINJ|wrapped INJ|`0x0000000088827d2d103ee2d9A6b781773AE03FfB`| +|USDC||`0x2a25fbD67b3aE485e461fe55d9DbeF302B7D3989`| +|MultiCall||`0xcA11bde05977b3631167028862bE2a173976CA11`| + +请使用下面的参考页面作为规范来源。 + +参考: [EVM 网络信息 | Injective | Docs](/cn/developers-evm/network-information#injective-evm-mainnet) + +# 跨链桥 + +[Injective Bridge](https://bridge.injective.network) + +指南: +- [如何使用 Metamask 从 Ethereum 桥接到 Injective](https://injective.com/blog/how-to-bridge-from-ethereum-to-injective-using-metamask/) +- [如何使用 Phantom 从 Solana 桥接到 Injective](https://injective.com/blog/how-to-bridge-from-solana-to-injective-using-phantom/) +- [如何使用 Wormhole 桥接到 Injective](https://injective.com/blog/how-to-bridge-to-injective-using-wormhole/) +- [如何使用 Keplr 从 Cosmos 桥接到 Injective](https://injective.com/blog/how-to-bridge-from-cosmos-to-injective-using-keplr/) + +# 数据 + +## 浏览器 + +- Explorer: [`blockscout.injective.network`](https://blockscout.injective.network/) +- Explorer API: [`blockscout-api.injective.network/api`](https://blockscout-api.injective.network/api) + +## 预言机 + +- API3: + - 价格源: [Api3 Market | Injective EVM](https://market.api3.org/injective) +- Pyth: + - 文档: [Pyth EVM Real Time Data Pull Integration](https://docs.pyth.network/price-feeds/core/use-real-time-data/pull-integration/evm) + - 参考文档: [Pyth EVM Smart Contract Addresses](https://docs.pyth.network/price-feeds/core/contract-addresses/evm) +- Chainlink: + - 文档: [Chainlink Data Streams](https://docs.chain.link/data-streams) + +# 钱包 + +## `injectived` + +适用于程序化控制,例如应用/dApp 操作的账户。 + +安装快速入门: + +```shell +wget https://github.com/InjectiveLabs/injective-chain-releases/releases/download/v1.17.2-1765930431/linux-amd64.zip # 替换为最新版本的 injective +unzip linux-amd64.zip +sudo mv injectived peggo /usr/bin +sudo mv libwasmvm.x86_64.so /usr/lib +``` + + +在上面的命令中,`wget` 下载的 URL 应替换为最新版本的 URL。 +你可以在 [Mainnet Validator](/infra/validator-mainnet) 部分找到确切的命令(包括 URL)。 + + + +更多选项,包括通过 Docker 安装或从源代码编译, +可在下面的参考页面中找到。 + + +参考: [injectived | Injective | Docs](/developers/injectived) + +## MetaMask + +适用于需要与 EVM DApp 交互的零售用户。 + +安装: + +- 从 [https://metamask.io/en-GB](https://metamask.io/en-GB) 获取适用于你特定浏览器的浏览器扩展。 +- 访问 [https://blockscout.injective.network/](https://blockscout.injective.network/),滚动到页面底部 +- 点击 "Add Injective" 按钮 +- 按照 MetaMask 用户界面中的提示操作 + +参考: [如何创建 Injective 钱包 (MetaMask)](https://injective.com/blog/how-to-create-an-injective-wallet-2/#to-connect-to-injective-with-metamask) + +## Keplr + +- Keplr : [https://www.keplr.app](https://www.keplr.app) +- Keplr API 集成文档: [https://docs.keplr.app/api/intro](https://docs.keplr.app/api/intro) + +参考: [如何创建 Injective 钱包 (Keplr)](https://injective.com/blog/how-to-create-an-injective-wallet-2#to-connect-to-injective-with-keplr) diff --git a/.gitbook/cn/developers-evm/evm-integrations-faq.mdx b/.gitbook/cn/developers-evm/evm-integrations-faq.mdx new file mode 100644 index 0000000..49f5c1a --- /dev/null +++ b/.gitbook/cn/developers-evm/evm-integrations-faq.mdx @@ -0,0 +1,110 @@ +--- +title: "EVM 集成常见问题" +description: 关于与 Injective EVM 集成的常见问题。 +--- + +## Injective EVM 是否支持...? + +**Injective EVM 是否支持(EVM 功能)?** + +答:通常,答案是"是"。 +请参阅下面更具体的问题。 + +**Injective EVM 是否支持这些特定的 opcodes?** + +答:是的。我们与 opcode 实现保持一致。 +更准确地说:我们没有添加任何自定义 opcodes, +也没有修改任何 opcodes 的行为。 + +**Injective EVM 是否支持 ERC20、ERC721、ERC1155?** + +答:是的,任何基于 Solidity 的智能合约标准都应该可以工作, +因为这些*不需要*标准 EVM 之外的任何特殊功能。 + +推论:在实现同质化 token 时, +ERC20 和任何其扩展, +我们强烈建议你将它们实现为 MultiVM Token Standard (MTS) token。 +这允许同一个 token 不仅在 Injective 的 EVM 上作为同质化 token, +还可以在 Injective 原生(特别是作为 Cosmos Denoms)上使用。 +如果 Injective 将来添加其他 VM,MTS token 也将在这些 VM 上工作。 +阅读更多关于 MTS 的信息: +[一般文章](https://injective.com/blog/multivm-token-standard-wrapped-inj),和 +[技术参考](/cn/developers-evm/multivm-token-standard)。 + +**Injective EVM 是否支持 EIP-1559?** + +答:是的。 + +## 我可以在 Injective EVM 上使用...吗? + +答:通常,答案是"是"。 +请参阅下面更具体的问题。 + +**我可以在 Injective EVM 上使用(EVM 工具/库)吗?** + +答: + +- viem - 是 +- ethers.js - 是 +- hardhat - 是 +- foundry - 是 + +**我可以在 Injective EVM 上使用 Foundry 与 Injective 的 EVM precompiles 吗?** + +答:Injective 的 [EVM precompiles](/cn/developers-evm/precompiles) +访问通用 EVM 中不可用的 Injective 原生功能。 +这意味着如果你使用 Foundry 并连接到: + +- Injective EVM Testnet,它将工作 +- `localhost` 模拟 EVM 网络,它将不工作 + +为解决后者的问题,我们 fork 了 Foundry 工具以支持 +Injective precompiles(从 `BankERC20.sol` 和 MTS 所需的 Bank precompile 开始), +如果你使用 Solidity 测试或部署脚本作为 Foundry 项目, +你将需要这个,以便 `forge`/`cast` 可以进行本地模拟。 + +最新版本,包含 x86_64 Linux 和 macOS ARM64 的预构建二进制文件, +可在 [github.com/InjectiveLabs/foundry/releases](https://github.com/InjectiveLabs/foundry/releases) 找到。 + +## Injective 上有哪些 EVM 开发基础设施? + +请参阅 [EVM 集成速查表](/cn/developers-evm/evm-integrations-cheat-sheet) +获取答案。 + +## 如何解决 JSON-RPC 丢弃响应? + +答:如果你使用公共 endpoint 进行 RPC, +由于速率限制,这很可能会发生在你身上。 +这些 endpoints 设计用于非常轻量的使用。 +如果你部署了复杂的应用, +你应该考虑使用商业级 RPC endpoint。 + +你可以在 +[EVM 集成速查表](/cn/developers-evm/evm-integrations-cheat-sheet) 中找到推荐的 RPC 提供商。 + +## `inj...` 地址和 `0x...` 地址兼容吗? + +答:是的。实际上它们是相同的,只是以不同的格式呈现。 + +请参阅 [转换地址](https://docs.injective.network/developers/convert-addresses) +获取在这两种格式之间转换的示例代码。 + +## Injective 支持哪个 EVM 硬分叉? + +答:这是 EVM 的实时配置数据: +[sentry.lcd.injective.network/injective/evm/v1/params](https://sentry.lcd.injective.network/injective/evm/v1/params) + +在 `chain_config` 下,有对应 EVM 硬分叉名称(带后缀)的键。 +这些表示哪些已启用。 +这些键的值是它们启用的区块号。 +截至 Mainnet 启动,所有这些都设置为 `0`, +即它们从"创世" EVM 区块启用。 +对于未来的 EVM 硬分叉,将添加新的键,其非零区块号 +表示它们将(或已经)启用的时间。 + + +你有更多关于 EVM 集成的问题吗? + +加入 [Injective discord](https://discord.com/invite/injective) +社区并在那里提问! + diff --git a/.gitbook/cn/developers-evm/exchange-precompile.mdx b/.gitbook/cn/developers-evm/exchange-precompile.mdx new file mode 100644 index 0000000..21fdf46 --- /dev/null +++ b/.gitbook/cn/developers-evm/exchange-precompile.mdx @@ -0,0 +1,166 @@ +--- +title: Exchange Precompile +--- + +Exchange Precompile 是一个位于固定地址 `0x0000000000000000000000000000000000000065` 的系统智能合约。它为 Solidity 开发者提供了一种高效且原生的方式来直接与 Injective 链的 exchange 模块交互。通过利用此 precompile,你的智能合约可以无缝执行各种与交易所相关的操作,包括: + +* 向/从子账户存入和提取资金。 +* 下单或取消现货和衍生品订单。 +* 查询子账户余额和持仓。 +* 管理对其他账户或合约的授权。 + +#### 调用 Precompile:直接访问 vs. 代理访问 + +与 Exchange Precompile 交互可以通过两种主要方式: + +**1. 直接访问(自调用合约)** + +在此模式下,你的智能合约代表自己与 precompile 交互。合约本身是在 exchange 模块上执行操作的参与者,使用自己的资金并管理自己的持仓。 + +_示例:_ + +``` +exchange.deposit(address(this), subaccountID, denom, amount); +``` + +此方法简单直接,**不需要显式授权**,因为合约本身有权管理自己的资源。 + +**2. 代理访问(代表其他用户调用)** + +智能合约也可以设计为中介,代表外部用户账户执行交易所操作。在这种情况下,合约调用 precompile,指定第三方的地址作为发送者或要操作的账户。 + +_示例:_ + +``` +exchange.deposit(userAddress, subaccountID, denom, amount); +``` + +为使此操作成功,智能合约(`grantee`)**必须被用户**(`userAddress`,即 `granter`)**显式授权**执行指定的操作。此授权使用 precompile 提供的 `approve` 和 `revoke` 方法管理。**谨慎处理这些授权以确保用户资金安全至关重要。** + +要授权合约代表你执行特定操作: + +``` +exchange.approve(grantee, msgTypes, spendLimit, duration); +``` + +* `grantee`:被授权的合约地址。 +* `msgTypes`:`grantee` 被授权执行的消息类型数组(例如 `MsgCreateDerivativeLimitOrder`、`MsgDeposit`)。请参阅 `ExchangeTypes.sol` 或 Injective Protocol protobuf 定义获取完整列表。 +* `spendLimit`:定义 `grantee` 可以使用的指定 token 的最大金额的 `Cosmos.Coin` 结构数组,按消息类型或整体授权。 +* `duration`:授权保持有效的时间段,以秒为单位。 + +要撤销之前授予的授权: + +``` +exchange.revoke(grantee, msgTypes); +``` + +要检查授权当前是否存在: + +``` +exchange.allowance(grantee, granter, msgType); +``` + +#### 示例:直接方法 + +下面的 `ExchangeDemo` 合约说明了智能合约如何使用直接访问方法。它执行基本的交易所操作,如存入资金、提取资金、创建衍生品限价订单和查询子账户持仓,所有这些都使用自己的子账户和资金。 + +`Exchange.sol` 和 `ExchangeTypes.sol` 文件包含与 precompile 交互所需的接口定义和数据结构。这些通常可在官方 Injective Solidity 合约仓库中找到,或可作为项目中的依赖项包含。 + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.4; + +import "../src/Exchange.sol"; // 包含 IExchangeModule 接口 +import "../src/ExchangeTypes.sol"; // 包含必要的结构如 DerivativeOrder + +contract ExchangeDemo { + address constant exchangeContract = 0x0000000000000000000000000000000000000065; + IExchangeModule exchange = IExchangeModule(exchangeContract); + + /*************************************************************************** + * 直接调用 precompile(合约代表自己操作) + ****************************************************************************/ + + /** + * @notice 将资金从合约余额存入其交易所子账户之一。 + * @param subaccountID 目标子账户 ID(从合约地址派生)。 + * @param denom 要存入的资产面额(例如 "inj")。 + * @param amount 要存入的资产数量。 + * @return success 表示存款是否成功的布尔值。 + */ + function deposit( + string calldata subaccountID, + string calldata denom, + uint256 amount + ) external returns (bool) { + try exchange.deposit(address(this), subaccountID, denom, amount) returns (bool success) { + return success; + } catch Error(string memory reason) { + revert(string(abi.encodePacked("Deposit error: ", reason))); + } catch { + revert("Unknown error during deposit"); + } + } + + /** + * @notice 从合约的交易所子账户之一提取资金到其主余额。 + * @param subaccountID 源子账户 ID。 + * @param denom 要提取的资产面额。 + * @param amount 要提取的资产数量。 + * @return success 表示提款是否成功的布尔值。 + */ + function withdraw( + string calldata subaccountID, + string calldata denom, + uint256 amount + ) external returns (bool) { + try exchange.withdraw(address(this), subaccountID, denom, amount) returns (bool success) { + return success; + } catch Error(string memory reason) { + revert(string(abi.encodePacked("Withdraw error: ", reason))); + } catch { + revert("Unknown error during withdraw"); + } + } + + /** + * @notice 查询此合约给定子账户的衍生品持仓。 + * @param subaccountID 要查询的子账户 ID。 + * @return positions DerivativePosition 结构数组。 + */ + function subaccountPositions( + string calldata subaccountID + ) external view returns (IExchangeModule.DerivativePosition[] memory positions) { + // 注意:调用 precompiles 的 view 函数可能根据节点配置表现不同 + // 对于链上状态,这没问题。对于链下查询,通常首选直接 gRPC/API 查询。 + return exchange.subaccountPositions(subaccountID); + } + + /** + * @notice 从合约的子账户创建新的衍生品限价订单。 + * @param order 包含订单详情的 DerivativeOrder 结构。 + * @return response 包含订单哈希等详情的响应结构。 + */ + function createDerivativeLimitOrder( + IExchangeModule.DerivativeOrder calldata order + ) external returns (IExchangeModule.CreateDerivativeLimitOrderResponse memory response) { + try exchange.createDerivativeLimitOrder(address(this), order) returns (IExchangeModule.CreateDerivativeLimitOrderResponse memory resp) { + return resp; + } catch Error(string memory reason) { + revert(string(abi.encodePacked("CreateDerivativeLimitOrder error: ", reason))); + } catch { + revert("Unknown error during createDerivativeLimitOrder"); + } + } +} +``` + +#### 开始构建 + +有关如何构建、部署和与此 `ExchangeDemo` 智能合约交互的详细说明,包括设置子账户和充值,请参阅我们 [solidity-contracts](https://github.com/InjectiveLabs/solidity-contracts/tree/master/demos/exchange) 仓库中提供的综合演示。 + +#### 结论 + +Exchange Precompile 是一个强大的工具,使复杂的、协议集成的交易逻辑能够直接嵌入你在 Injective 上的智能合约中。无论你的合约是管理自己的投资组合还是作为其他用户的多功能交易接口(通过带有 `approve` 和 `revoke` 的代理模式),此 precompile 都提供了一种干净、安全且高效的方法来使用 Solidity 与核心 exchange 模块交互。 + +请记住,对于自包含的合约逻辑优先使用直接调用,并在为更广泛的 Injective 生态系统构建可重用合约接口时谨慎实现带有强大授权的代理模式。 diff --git a/.gitbook/cn/developers-evm/index.mdx b/.gitbook/cn/developers-evm/index.mdx new file mode 100644 index 0000000..d1d47c0 --- /dev/null +++ b/.gitbook/cn/developers-evm/index.mdx @@ -0,0 +1,46 @@ +--- +title: 概述 +--- + +欢迎 EVM 开发者!Injective 原生 EVM 支持让你可以部署 Solidity 智能合约。它还开启了与 exchange 模块交互、构建 dApp 等更多可能性。现在你可以使用熟悉的工具、库和工作流程在 Injective 上进行开发! + +## 开始在 EVM 上构建 + + + + 设置与 Injective EVM 的连接 + + + 编写 **Solidity** 代码,然后编译、测试、部署、验证并与**智能合约**交互。 + + + EVM 接口,允许智能合约与 Injective 链的原生功能交互 + + + INJ Faucet + + diff --git a/.gitbook/cn/developers-evm/infrastructure-and-tooling.mdx b/.gitbook/cn/developers-evm/infrastructure-and-tooling.mdx new file mode 100644 index 0000000..1852703 --- /dev/null +++ b/.gitbook/cn/developers-evm/infrastructure-and-tooling.mdx @@ -0,0 +1,39 @@ +--- +description: 使用世界级基础设施在 Injective 上构建 +title: 基础设施和工具 +--- + +Injective 由丰富的行业领先基础设施提供商生态系统支持。访问可靠的 RPC、强大的数据索引器以及构建和扩展 dApp 所需的所有工具,在最快的金融 L1 上。 + +### RPC 和节点提供商 + +
TenderlyTenderly 是一个提供高级交易模拟的平台,使用户能够在不广播到链上的情况下预览和分析 Ethereum 和 EVM 兼容交易。它还提供强大的调试工具,包括逐步执行跟踪和错误报告,帮助开发者高效识别和修复智能合约中的问题。
QuickNode使用最快的 RPC 节点、全面的 web3 API 库和最高性能的区块链 ETL 工具在 Injective 上构建。
+ +### **数据索引和查询** + + + + + + + + + + +
The Graph +

+The Graph 的最先进的 Substreams 和 Substreams 驱动的 subgraph 解决方案,由 StreamingFast 为 Injective 开发,为开发者提供对链上数据的无缝访问。 +

+ +
+ +### 区块浏览器 + +
BlockScoutEVM 标准区块浏览器
BlockScout CloudEVM 标准区块浏览器(由 BlockScout 托管)
diff --git a/.gitbook/cn/developers-evm/multivm-token-standard.mdx b/.gitbook/cn/developers-evm/multivm-token-standard.mdx new file mode 100644 index 0000000..b4eb030 --- /dev/null +++ b/.gitbook/cn/developers-evm/multivm-token-standard.mdx @@ -0,0 +1,72 @@ +--- +description: 了解 Injective 多 VM 架构中的 token 表示 +title: MultiVM Token Standard +--- + +## 什么是 MultiVM Token Standard (MTS)? + +MTS(MultiVM Token Standard)确保 Injective 上的每个 token,无论是使用 Cosmos 模块还是通过 Ethereum Virtual Machine (EVM) 部署的,都有一个规范的余额和身份。这种统一的方法防止了碎片化,消除了桥接或包装 token 的需要,从而实现了去中心化金融(DeFi)和 dApp 交互的无缝互操作性和统一流动性。 + +## 为什么 MTS 很重要? + +* **无缝互操作性:** Token 在 Cosmos 和 EVM 环境中保持一致。 +* **统一流动性:** 单一的真实来源避免了流动性碎片化。 +* **增强的开发者体验:** Hardhat、Foundry 和 MetaMask 等标准工具开箱即用。 +* **安全性和效率:** 所有 token 状态都集中维护在 bank 模块中,确保强大的安全性。 + +## 架构 + +系统由两个主要组件组成: + +* [**Bank Precompile**](/cn/developers-evm/bank-precompile/): + * 用 Go 开发,此 precompile 直接嵌入 Injective EVM 中。 + * 它提供了一个 Solidity 接口,将 ERC20 操作(如 mint、burn 和 transfer)代理到 bank 模块。 +* [**ERC20 Module**](/cn/developers-evm/erc20-module/): + * 此模块将原生 bank denom(例如 INJ、IBC token、Peggy 资产)映射到 EVM 中的 ERC20 合约。 + * 它部署符合 MTS 的 ERC20 合约,始终反映 bank 模块维护的规范 token 余额。 + +

单一 Token 表示架构

+ +### **创建符合 MTS 的 Token** + +1. [**使用我们的预构建模板**](https://github.com/InjectiveLabs/solidity-contracts/tree/master/src): + * 从提供的 Solidity 模板开始,如 `BankERC20.sol`、`MintBurnBankERC20.sol` 或 `FixedSupplyBankERC20.sol`。 +2. [**部署合约**](/cn/developers-evm/smart-contracts/): + * 在 Injective EVM 网络上部署你的 MTS token 合约。 + * 合约自动与 Bank Precompile 交互以更新规范状态。 + +### **互操作性和跨链集成** + +#### **原生互操作性** + +Injective 的 EVM 直接集成到基于 Cosmos 的链中。 + +* 使用 MTS 的 EVM 智能合约执行的操作会立即反映在原生模块(如 exchange、staking 和 governance 模块)上。 +* Injective 二进制文件中提供的 [JSON-RPC endpoints](/cn/developers-evm/network-information/) 与 Ethereum 兼容,确保开发者集成顺畅。 + +#### **跨链操作** + +* **IBC 兼容性:** 现有的原生 token(例如通过 [Token Factory](/developers-native/injective/tokenfactory/) 创建或通过 Peggy 锚定的)一旦建立 MTS 配对,就可以从 EVM 访问。 +* **桥接替代方案:** 虽然许多区块链需要单独的桥接操作(锁定、铸造、解锁),但 MTS 通过原生同步状态避免了这些步骤。 + +#### **Allowances 和扩展 ERC20 功能** + +* MTS 合约维护标准 ERC20 功能,如 allowances(approve/transferFrom)。 +* 请注意,虽然 allowance 机制在 EVM 合约中维护以方便使用,但最终余额由 bank 模块管理,保持完整性。 + +### **性能、Gas 和安全考虑** + +#### **Gas 成本和效率** + +* Gas 费用以 INJ 支付。虽然通过 EVM 的 MTS 操作引入了一个抽象层,可能会略微增加 gas 使用量,但与 Ethereum 上的类似操作相比,总体成本仍然较低。 +* Gas 模型旨在平衡 EVM 风格的 opcode 成本和原生模块交互。 + +#### **安全性** + +* [bank 模块](/developers-native/core/)作为单一真实来源,通过确保 token 余额一致且可验证来支撑 MTS 的安全性。 +* 使用 [precompiles](/cn/developers-evm/precompiles/) 可防止状态不同步等常见陷阱,确保所有操作(无论从何处发起)都更新同一个规范账本。 +* 智能合约开发的高级安全指南和最佳实践在我们的安全部分和外部资源中提供。 + +**ℹ️ 注意:** + +为防止 denom 垃圾信息,通过 ERC20 模块部署 ERC20 合约是**付费操作**,需要 **1 INJ** 的部署费用。确保你的 ERC20 合约部署交易包含此金额,否则操作将被拒绝。 diff --git a/.gitbook/cn/developers-evm/network-information.mdx b/.gitbook/cn/developers-evm/network-information.mdx new file mode 100644 index 0000000..d844ebd --- /dev/null +++ b/.gitbook/cn/developers-evm/network-information.mdx @@ -0,0 +1,111 @@ +--- +description: Injective EVM 网络的基本信息 +title: EVM 网络信息 +--- + + + + + +## 网络信息 + +* Chain ID: `1776` +* JSON-RPC Endpoint: `https://sentry.evm-rpc.injective.network/` +* WS Endpoint: `wss://sentry.evm-ws.injective.network` +* Faucet: 不适用,获取 Mainnet INJ 请访问 [`injective.com/getinj`](https://injective.com/getinj/) +* Explorer: [`blockscout.injective.network`](https://blockscout.injective.network/) +* Explorer API: `https://blockscout-api.injective.network/api` + + +请注意,Injective Chain ID 原生为 `injective-1`。 +但是,EVM 使用数字 Chain ID `1776`。 +虽然这两者不同,但它们映射到**同一个**网络。 + +更多详情请参阅 [Injective Mainnet 网络信息](/developers/network-information/#injective-mainnet)。 + + +## 合约 + +* **USDT** USDT (MTS) - [`0x88f7F2b685F9692caf8c478f5BADF09eE9B1Cc13`](https://blockscout.injective.network/address/0x88f7F2b685F9692caf8c478f5BADF09eE9B1Cc13) +* **wETH** wrapped ETH (MTS) - [`0x83A15000b753AC0EeE06D2Cb41a69e76D0D5c7F7`](https://blockscout.injective.network/address/0x83A15000b753AC0EeE06D2Cb41a69e76D0D5c7F7) +* **wINJ** wrapped INJ (MTS) - [`0x0000000088827d2d103ee2d9A6b781773AE03FfB`](https://blockscout.injective.network/address/0x0000000088827d2d103ee2d9A6b781773AE03FfB) +* **USDC** USDC (MTS) - [`0x2a25fbD67b3aE485e461fe55d9DbeF302B7D3989`](https://blockscout.injective.network/address/0x2a25fbD67b3aE485e461fe55d9DbeF302B7D3989) +* **MultiCall** - [`0xcA11bde05977b3631167028862bE2a173976CA11`](https://blockscout.injective.network/address/0xcA11bde05977b3631167028862bE2a173976CA11) + + +请注意,标记为 **MTS** 的 token 遵循 [MultiVM Token Standard](https://docs.injective.network/developers-evm/multivm-token-standard)。 + +这意味着同一个 token 可以在所有 Injective 模块(EVM、Cosmos)中使用,无需使用跨链桥。 + + +## 更多提供商 + +* Explorers + * Blockscout 镜像: [`injective.cloud.blockscout.com`](https://injective.cloud.blockscout.com) +* JSON-RPC 提供商 + * Quicknode [`quicknode.com/chains/inj`](https://www.quicknode.com/chains/inj) + * 请注意,你需要在 quicknode 上创建账户才能获取 endpoint URL + * [Quicknode JSON-RPC 文档](https://www.quicknode.com/docs/injective/evm/eth_blockNumber) + * ThirdWeb [`thirdweb.com/injective`](https://thirdweb.com/injective) + * 请注意,你需要在 thirdweb 上创建账户才能获取 endpoint URL + * [ThirdWeb Playground](https://playground.thirdweb.com/) + + + + + +## 网络信息 + +* Chain ID: `1439` +* JSON-RPC Endpoint: `https://k8s.testnet.json-rpc.injective.network/` +* WS Endpoint: `https://k8s.testnet.ws.injective.network/` +* Faucet: [`testnet.faucet.injective.network/`](https://testnet.faucet.injective.network/) +* Explorer: [`testnet.blockscout.injective.network/`](https://testnet.blockscout.injective.network/) +* Explorer API: `https://testnet.blockscout-api.injective.network/api` + + + +请注意,Injective Chain ID 原生为 `injective-888`。但是,EVM 使用数字 Chain ID `1439`。虽然这两者不同,但它们映射到**同一个**网络。 + +更多详情请参阅 [Injective Testnet 网络信息](/developers/network-information/#injective-testnet)。 + + +## 合约 + +* **wINJ** wrapped INJ (MTS) - [`0x0000000088827d2d103ee2d9A6b781773AE03FfB`](https://testnet.blockscout.injective.network/address/0x0000000088827d2d103ee2d9A6b781773AE03FfB) +* **USDT** USDT (MTS) - [`0xaDC7bcB5d8fe053Ef19b4E0C861c262Af6e0db60`](https://testnet.blockscout.injective.network/address/0xaDC7bcB5d8fe053Ef19b4E0C861c262Af6e0db60) + + +请注意,标记为 **MTS** 的 token 遵循 [MultiVM Token Standard](https://docs.injective.network/developers-evm/multivm-token-standard)。 + +这意味着同一个 token 可以在所有 Injective 模块(EVM、Cosmos)中使用,无需使用跨链桥。 + + +## 更多提供商 + +* Explorers + * Blockscout 镜像: [`testnet-injective.cloud.blockscout.com/`](https://testnet-injective.cloud.blockscout.com/) +* JSON-RPC 提供商 + * Quicknode [`quicknode.com/chains/inj`](https://www.quicknode.com/chains/inj) + * 请注意,你需要在 quicknode 上创建账户才能获取 endpoint URL + * [Quicknode JSON-RPC 文档](https://www.quicknode.com/docs/injective/evm/eth_blockNumber) + * ThirdWeb [`thirdweb.com/injective-evm-testnet`](https://thirdweb.com/injective-evm-testnet) + * 请注意,你需要在 thirdweb 上创建账户才能获取 endpoint URL + * [ThirdWeb Playground](https://playground.thirdweb.com/) + +## 更多信息 + +有关 Injective EVM Testnet 的更多信息,请参阅以下页面: + +* 基础: + * [开始在 EVM 上构建](/cn/developers-evm) + * [你的第一个 EVM 智能合约](/cn/developers-evm/smart-contracts) + * [你的第一个 EVM dApp](/cn/developers-evm/dapps) +* 进阶: + * [EVM 等效性](/cn/developers-evm/evm-equivalence) + * [MultiVM Token Standard](/cn/developers-evm/multivm-token-standard) + * [Precompiles](/cn/developers-evm/precompiles) + + + + diff --git a/.gitbook/cn/developers-evm/precompiles.mdx b/.gitbook/cn/developers-evm/precompiles.mdx new file mode 100644 index 0000000..9da8d26 --- /dev/null +++ b/.gitbook/cn/developers-evm/precompiles.mdx @@ -0,0 +1,82 @@ +--- +title: Precompiles +--- + +### 什么是 Injective 上的 Precompiles? + +在 Injective 上,precompiles 是直接嵌入我们 EVM(Ethereum Virtual Machine)层协议级别的特殊、高度优化的智能合约。与用户部署的标准 Solidity 智能合约不同,precompiles 是链核心逻辑的一部分。它们用 Go 而不是 Solidity 编写,并以固定地址暴露给 EVM,使它们可以像任何其他智能合约一样从你的 Solidity 智能合约中调用。 + +可以将它们视为 Injective 链的原生功能,被赋予了 Ethereum 风格的接口。 + +### 为什么它们是必要的?(桥接 EVM 和原生模块) + +Injective EVM 不是孤立运行的。它与 Injective 强大的原生 Cosmos SDK 模块深度集成,如 Bank 模块(用于 token 管理)、Exchange 模块(用于链上订单簿)、Staking 模块等。 + +Precompiles 作为 EVM 世界(你的 Solidity 合约所在的地方)和这些原生 Injective 功能之间的关键**桥梁**。没有 precompiles,你的 EVM 智能合约将被隔离,无法利用更广泛的 Injective 生态系统的丰富功能和流动性。 + +例如,我们的 [MultiVM Token Standard (MTS)](/cn/developers-evm/multivm-token-standard) 模型,确保原生和 EVM 环境之间统一的 token 余额,严重依赖于 **Bank Precompile**。 + +### 对开发者的好处 + +* **访问原生功能:** 直接与 Injective 的独特模块交互,如链上订单簿、原生 staking、governance 和用于 MTS 的 bank 模块。 +* **增强的性能:** 通过 precompiles 执行的操作可以比纯粹在 Solidity 中复制复杂原生逻辑更快、更节省 gas,因为它们作为优化的原生代码运行。 +* **无缝互操作性:** 构建真正集成的应用,利用 EVM 和 Injective 的 Cosmos 原生能力的优势。 +* **简化开发:** 通过熟悉的 Solidity 接口与复杂的原生功能交互,抽象掉大部分底层 Cosmos 复杂性。 + +一系列由 Bank precompile 支持的 ERC-20 实现,以及 precompile 接口和抽象合约,可在 [Injective 的 Solidity 合约仓库](https://github.com/InjectiveLabs/solidity-contracts) 中找到。关键合约包括: + +* [**Bank.sol**](https://github.com/InjectiveLabs/solidity-contracts/blob/master/src/Bank.sol) – precompile 接口 +* [**BankERC20.sol**](https://github.com/InjectiveLabs/solidity-contracts/blob/master/src/BankERC20.sol) – 由 Bank precompile 支持的抽象 ERC20 实现 +* [**FixedSupplyBankERC20.sol**](https://github.com/InjectiveLabs/solidity-contracts/blob/master/src/FixedSupplyBankERC20.sol) – 固定供应量的去中心化 ERC20(无所有者,无铸造或销毁) +* [**MintBurnBankERC20.sol**](https://github.com/InjectiveLabs/solidity-contracts/blob/master/src/MintBurnBankERC20.sol) – 具有授权铸造和销毁 token 的所有者的 ERC20 + +这些实现基于 OpenZeppelin 的 ERC20 合约。开发者可以自由创建使用 Bank precompile 的自定义 ERC20 合约。 + +### 入门演示 + +我们准备了一些演示,展示如何使用 Bank、Exchange 和 Staking precompiles 构建合约。这些示例还演示了如何使用最常见的 Ethereum 开发框架 **Foundry** 与 Injective EVM 交互。 + +通过利用 Foundry 的 `cast` 工具,你可以轻松地直接从终端部署合约并与 Injective 链交互。这使构建者能够快速实验、测试和部署利用 Injective 原生模块的强大应用。 + +探索以下演示以了解: + +- 如何编写调用 precompiles 进行 token 管理、交易和 staking 的 Solidity 合约。 +- 如何使用 Foundry 脚本和 `cast` 命令在 Injective EVM 上部署和与这些合约交互。 +- 桥接 EVM 逻辑与 Injective 原生功能的最佳实践。 + +通过克隆 [Injective Solidity 合约仓库](https://github.com/InjectiveLabs/solidity-contracts/tree/master/demos) 并按照每个演示目录中的分步指南开始你的开发。 + +* [Bank Precompile 演示](https://github.com/InjectiveLabs/solidity-contracts/tree/master/demos/erc20) +* [Exchange Precompile 演示](https://github.com/InjectiveLabs/solidity-contracts/tree/master/demos/exchange) +* [Staking Precompile 演示](https://github.com/InjectiveLabs/solidity-contracts/tree/master/demos/staking) + +### Precompile 地址 + +| 名称 | 用途 | EVM 地址 | +| ---------------------------------- | ----------------------------- | ----------- | +| [Bank](/cn/developers-evm/bank-precompile) | Token 管理 | `0x64` | +| [Exchange](/cn/developers-evm/exchange-precompile) | 链上订单簿 | `0x65` | +| Staking | 原生 staking token 链上 | `0x66` | + +## 非合约地址错误 + +使用 Foundry 时,如果你在本地 "fork" Injective Mainnet 或 Injective Testnet, +并在该环境中执行你的智能合约, +你可能会看到类似以下的错误: + +```text +[Revert] call to non-contract address 0x0000000000000000000000000000000000000064 +``` + +这是因为 Foundry 在本地*模拟* Injective, +而不是实际在 Injective 上运行。 +因此它运行的是*通用 EVM* 模拟, +而不是特定于 Injective 的模拟。 +区别在于 Injective 的原生功能不存在, +因此它不知道 precompiles。 + +解决方法很简单: +使用已修补以包含 Injective precompiles 的 Foundry 版本: +[github.com/InjectiveLabs/foundry/releases](https://github.com/InjectiveLabs/foundry/releases)。 + +这些包括 x86_64 Linux 和 macOS ARM64 的预构建二进制文件。 diff --git a/.gitbook/cn/developers-evm/smart-contracts/compile-foundry.mdx b/.gitbook/cn/developers-evm/smart-contracts/compile-foundry.mdx new file mode 100644 index 0000000..4838217 --- /dev/null +++ b/.gitbook/cn/developers-evm/smart-contracts/compile-foundry.mdx @@ -0,0 +1,150 @@ +--- +title: 设置 Foundry 并编译智能合约 +--- + +## 前置条件 + +确保你已安装 Foundry,运行以下命令: + +```shell +forge --version +``` + +请注意,本教程使用的版本是 `1.2.3-stable`。请确保在跟随操作时使用此版本或更高版本。 + +如果你还没有 foundry,运行以下命令安装: + +```shell +curl -L https://foundry.paradigm.xyz | bash +``` + + +还有其他安装 Foundry 的选项。 +请参阅 [Foundry 安装文档](https://getfoundry.sh/introduction/installation)。 + + +你需要一个钱包,以及一个已充值 Testnet INJ 的账户。 + + +你可以从 [Injective Testnet faucet](https://testnet.faucet.injective.network/) 申请 EVM testnet 资金。 + + +创建账户后,请务必将私钥复制到可访问的位置,因为你需要它来完成本教程。 + + +请注意,私钥应谨慎处理。 +此处的说明仅适用于本地开发和 Testnet。 +但是,这些方法对于 Mainnet 上使用的私钥来说**不够**安全。 +请确保在 Mainnet 上遵循密钥安全的最佳实践,并且不要在 Mainnet 和其他网络之间重复使用相同的密钥/账户。 + + +## 设置新的 Foundry 项目 + +使用 git 克隆演示仓库,该仓库已为你完全设置好项目。 + +```shell +git clone https://github.com/injective-dev/foundry-inj +cd foundry-inj +``` + +安装 `forge-std` 库,它提供了本项目中使用的实用函数。 + +```shell +forge install foundry-rs/forge-std +``` + +## 项目结构 + +在代码编辑器/IDE 中打开仓库,查看目录结构。 + +```text +foundry-inj/ + src/ + Counter.sol → 智能合约 Solidity 代码 + test/ + Counter.t.sol → 测试用例 + foundry.toml → 配置文件 +``` + +`foundry.toml` 文件已预配置为连接到 Injective EVM Testnet。 +在继续之前,你只需要提供 Injective Testnet 账户的私钥。 + +输入以下命令导入私钥,并将其保存到名为 `injTest` 的账户: + +```shell +cast wallet import injTest --interactive +``` + +这将提示你输入私钥,以及每次使用此账户时需要输入的密码。 +使用你之前创建并充值的账户的私钥(例如通过 Injective Testnet faucet)。 +请注意,当你输入或粘贴私钥和密码的文本时,终端中不会显示任何内容。 +输出应该类似于: + +```text +Enter private key: +Enter password: +`injTest` keystore was saved successfully. Address: 0x58f936cb685bd6a7dc9a21fa83e8aaaf8edd5724 +``` + + +这会将私钥的加密版本保存在 `~/.foundry/keystores` 中, +在后续命令中可以使用 `--account` CLI 标志访问。 + + +## 编辑智能合约 + +此演示中包含的智能合约非常基础。它: + +- 存储一个 `value`,这是一个数字。 +- 暴露一个 `value()` 查询方法。 +- 暴露一个 `increment(num)` 交易方法。 + +打开文件:`src/Counter.sol` + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity 0.8.28; + +contract Counter { + uint256 public value = 0; + + function increment(uint256 num) external { + value += num; + } +} + +``` + +## 编译智能合约 + +运行以下命令: + +```shell +forge build +``` + +Foundry 将自动下载并运行在 `foundry.toml` 文件中配置的 Solidity 编译器(`solc`)版本。 + +## 检查编译输出 + +编译器完成后,你应该在项目目录中看到额外的目录: + +```text +foundry-inj/ + cache/ + ... + out/ + build-info/ + ... + Counter.sol/ + Counter.json → 打开此文件 +``` + +打开 `Counter.json` 文件(`out/Counter.sol/Counter.json`)。 +在其中,你应该看到编译器输出,包括 `abi` 和 `bytecode` 字段。 +这些 artifacts 将在后续所有步骤(测试、部署、验证和交互)中使用。 + +## 下一步 + +现在你已经设置了 Foundry 项目并编译了智能合约,你可以开始测试该智能合约了! +接下来请查看[使用 Foundry 测试智能合约](./test-foundry/)教程。 diff --git a/.gitbook/cn/developers-evm/smart-contracts/compile-hardhat.mdx b/.gitbook/cn/developers-evm/smart-contracts/compile-hardhat.mdx new file mode 100644 index 0000000..d824aa3 --- /dev/null +++ b/.gitbook/cn/developers-evm/smart-contracts/compile-hardhat.mdx @@ -0,0 +1,144 @@ +--- +title: 设置 Hardhat 并编译智能合约 +--- + +## 前置条件 + +确保你已安装较新版本的 NodeJs。 +你可以使用以下命令检查: + +```shell +node -v +``` + +本指南使用的版本为: + +```text +v22.16.0 +``` + +如果你尚未安装 NodeJs,请使用以下方式安装: + +- Linux 或 Mac: [NVM](https://github.com/nvm-sh/nvm) +- Windows: [NVM for Windows](https://github.com/coreybutler/nvm-windows) + +你需要一个钱包,以及一个已充值 Testnet INJ 的账户。 + + +你可以从 [Injective Testnet faucet](https://testnet.faucet.injective.network/) 申请 EVM testnet 资金。 + + +创建账户后,请务必将私钥复制到可访问的位置,因为你需要它来完成本教程。 + + +请注意,私钥应谨慎处理。 +此处的说明仅适用于本地开发和 Testnet。 +但是,这些方法对于 Mainnet 上使用的私钥来说**不够**安全。 +请确保在 Mainnet 上遵循密钥安全的最佳实践,并且不要在 Mainnet 和其他网络之间重复使用相同的密钥/账户。 + + +## 设置新的 Hardhat 项目 + +使用 git 克隆演示仓库,该仓库已为你完全设置好项目。 + +```shell +git clone https://github.com/injective-dev/hardhat-inj +``` + +从 npm 安装依赖: + +```shell +npm install +``` + +## 项目结构 + +在等待 npm 下载和安装时,在代码编辑器/IDE 中打开仓库,查看目录结构。 + +```text +hardhat-inj/ + contracts/ + Counter.sol → 智能合约 Solidity 代码 + script/ + deploy.js → 部署脚本 + test/ + Counter.test.js → 测试用例 + hardhat.config.js → 配置文件 + .example.env +``` + +`hardhat.config.js` 文件已预配置为连接到 Injective EVM Testnet。 +在继续之前,你只需要提供 Injective Testnet 账户的私钥。 + +```shell +cp .example.env .env +``` + +编辑 `.env` 文件以添加私钥。 +你也可以选择更新为其他 JSON-RPC endpoints。 + +```shell +PRIVATE_KEY=你的私钥(不带 0x 前缀) +INJ_TESTNET_RPC_URL=https://k8s.testnet.json-rpc.injective.network/ + +``` + +## 编辑智能合约 + +此演示中包含的智能合约非常基础。它: + +- 存储一个 `value`,这是一个数字。 +- 暴露一个 `value()` 查询方法。 +- 暴露一个 `increment(num)` 交易方法。 + +打开文件:`contracts/Counter.sol` + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity 0.8.28; + +contract Counter { + uint256 public value = 0; + + function increment(uint256 num) external { + value += num; + } +} + +``` + +## 编译智能合约 + +运行以下命令: + +```shell +npx hardhat compile +``` + +Hardhat 将自动下载并运行在 `hardhat.config.js` 文件中配置的 Solidity 编译器(`solc`)版本。 + +## 检查编译输出 + +编译器完成后,你应该在项目目录中看到额外的目录: + +```text +hardhat-inj/ + artifacts/ + build-info/ + ... + contracts/ + Counter.sol/ + Counter.json → 打开此文件 + ... + cache/ + ... +``` + +打开 `Counter.json` 文件(`artifacts/contracts/Counter.sol/Counter.json`)。 +在其中,你应该看到编译器输出,包括 `abi` 和 `bytecode` 字段。 +这些 artifacts 将在后续所有步骤(测试、部署、验证和交互)中使用。 + +## 下一步 + +现在你已经设置了 Hardhat 项目并编译了智能合约,你可以开始测试该智能合约了! +接下来请查看[使用 Hardhat 测试智能合约](./test-hardhat/)教程。 diff --git a/.gitbook/cn/developers-evm/smart-contracts/deploy-foundry.mdx b/.gitbook/cn/developers-evm/smart-contracts/deploy-foundry.mdx new file mode 100644 index 0000000..988a788 --- /dev/null +++ b/.gitbook/cn/developers-evm/smart-contracts/deploy-foundry.mdx @@ -0,0 +1,50 @@ +--- +title: 使用 Foundry 部署智能合约 +--- + +## 前置条件 + +你应该已经设置好 Foundry 项目,并成功编译了智能合约。 +请参阅[设置 Foundry 并编译智能合约](./compile-foundry/)教程了解如何操作。 + +可选但强烈推荐:你还应该已经成功测试了智能合约。 +请参阅[使用 Foundry 测试智能合约](./test-foundry/)教程了解如何操作。 + +## 运行部署 + +运行以下命令来部署智能合约: + +```shell +forge create \ + src/Counter.sol:Counter \ + --rpc-url injectiveEvm \ + --legacy \ + --account injTest \ + --gas-price 160000000 \ + --gas-limit 2000000 \ + --broadcast +``` + + +请注意,我们使用的是保存到 keystore 的 `injTest` 账户, +这是之前在[设置 Foundry 并编译智能合约](./compile-foundry/)中设置的。 + + +输出应该类似于: + +```text +Enter keystore password: +Deployer: 0x58f936cb685Bd6a7dC9a21Fa83E8aaaF8EDD5724 +Deployed to: 0x213bA803265386C10CE04a2cAa0f31FF3440b9cF +Transaction hash: 0x6aa9022f593083c7779da014a3032efd40f3faa2cf3473f4252a8fbd2a80db6c +``` + +复制部署的地址,访问 [`https://testnet.blockscout.injective.network`](https://testnet.blockscout.injective.network/),并在搜索字段中粘贴地址。 +你将访问区块浏览器中你刚刚部署的智能合约页面。 + +如果你点击 "Contract" 标签,你应该看到该合约的 EVM bytecode,它将与编译后在 artifacts 目录中找到的 EVM bytecode 匹配。 + +## 下一步 + +现在你已经部署了智能合约,你可以开始验证该智能合约了! +接下来请查看[使用 Foundry 验证智能合约](./verify-foundry/)教程。 diff --git a/.gitbook/cn/developers-evm/smart-contracts/deploy-hardhat.mdx b/.gitbook/cn/developers-evm/smart-contracts/deploy-hardhat.mdx new file mode 100644 index 0000000..27853a5 --- /dev/null +++ b/.gitbook/cn/developers-evm/smart-contracts/deploy-hardhat.mdx @@ -0,0 +1,58 @@ +--- +title: 使用 Hardhat 部署智能合约 +--- + +## 前置条件 + +你应该已经设置好 Hardhat 项目,并成功编译了智能合约。 +请参阅[设置 Hardhat 并编译智能合约](./compile-hardhat/)教程了解如何操作。 + +可选但强烈推荐:你还应该已经成功测试了智能合约。 +请参阅[使用 Hardhat 测试智能合约](./test-hardhat/)教程了解如何操作。 + +## 编辑部署脚本 + +为了让你在计算机上编译的智能合约存在于 Injective Testnet 上,需要将其部署到网络上。 + +为此,我们将使用一个脚本,该脚本使用由 Hardhat 预配置的 `ethers` 实例,使用 `hardhat.config.js` 中指定的值。 + +打开文件:`script/deploy.js` + +```js +async function main() { + const Counter = await ethers.getContractFactory('Counter'); + const counter = await Counter.deploy({ + gasPrice: 160e6, + gasLimit: 2e6, + }); + await counter.waitForDeployment(); + const address = await counter.getAddress(); + + console.log('Counter smart contract deployed to:', address); +} +``` + +还记得编译智能合约后,我们查看了 `artifacts/contracts/Counter.sol/Counter.json` 吗?在这个脚本中,`ethers.getContractFactory('Counter')` 检索该文件,并从中提取 ABI 和 EVM bytecode。 +接下来的几行使用该信息构造部署交易并将其提交到网络。 +如果成功,将输出你的智能合约部署的地址,例如: +[`0x98798cc92651B1876e9Cc91EcBcfe64cac720a1b`](https://testnet.blockscout.injective.network/address/0x98798cc92651B1876e9Cc91EcBcfe64cac720a1b) + +请注意,在其他 EVM 网络上,交易(包括部署交易)不需要指定 gas price 和 gas limit。但是,目前在 Injective 上这是必要的。 + +## 运行部署脚本 + +运行以下命令来部署智能合约: + +```shell +npx hardhat run script/deploy.js --network inj_testnet +``` + +复制部署的地址,访问 [`https://testnet.blockscout.injective.network`](https://testnet.blockscout.injective.network/),并在搜索字段中粘贴地址。 +你将访问区块浏览器中你刚刚部署的智能合约页面。 + +如果你点击 "Contract" 标签,你应该看到该合约的 EVM bytecode,它将与编译后在 artifacts 目录中找到的 EVM bytecode 匹配。 + +## 下一步 + +现在你已经部署了智能合约,你可以开始验证该智能合约了! +接下来请查看[使用 Hardhat 验证智能合约](./verify-hardhat/)教程。 diff --git a/.gitbook/cn/developers-evm/smart-contracts/index.mdx b/.gitbook/cn/developers-evm/smart-contracts/index.mdx new file mode 100644 index 0000000..48db6f6 --- /dev/null +++ b/.gitbook/cn/developers-evm/smart-contracts/index.mdx @@ -0,0 +1,35 @@ +--- +title: 你的第一个 EVM 智能合约 +--- + +智能合约是在区块链上运行的代码。 +你可以编译 Solidity 智能合约, +并在 Injective 的 Ethereum Virtual Machine (EVM) 上进行测试、部署、验证和交互。 +你也可以使用标准的 EVM 开发工具和框架来完成这些操作。 +以下指南将向你展示如何使用 Hardhat 和 Foundry 来实现。 + +## Hardhat + +本指南将引导你使用 [Hardhat](https://hardhat.org/) 在 Injective Testnet 上构建 EVM 智能合约。 + +* [设置 Hardhat 并编译智能合约](/cn/developers-evm/smart-contracts/compile-hardhat/) +* [使用 Hardhat 测试智能合约](/cn/developers-evm/smart-contracts/test-hardhat/) +* [使用 Hardhat 部署智能合约](/cn/developers-evm/smart-contracts/deploy-hardhat/) +* [使用 Hardhat 验证智能合约](/cn/developers-evm/smart-contracts/verify-hardhat/) +* [使用 Hardhat 与智能合约交互](/cn/developers-evm/smart-contracts/interact-hardhat/) + +## Foundry + +本指南将引导你使用 [Foundry](https://getfoundry.sh/) 在 Injective Testnet 上构建 EVM 智能合约。 + +* [设置 Foundry 并编译智能合约](/cn/developers-evm/smart-contracts/compile-foundry/) +* [使用 Foundry 测试智能合约](/cn/developers-evm/smart-contracts/test-foundry/) +* [使用 Foundry 部署智能合约](/cn/developers-evm/smart-contracts/deploy-foundry/) +* [使用 Foundry 验证智能合约](/cn/developers-evm/smart-contracts/verify-foundry/) +* [使用 Foundry 与智能合约交互](/cn/developers-evm/smart-contracts/interact-foundry/) + +## 下一步 + +智能合约不能为非技术用户提供用户体验。 +为了服务他们,你需要构建一个去中心化应用。 +请查看[你的第一个 dApp](/cn/developers-evm/dapps/) 指南! diff --git a/.gitbook/cn/developers-evm/smart-contracts/interact-foundry.mdx b/.gitbook/cn/developers-evm/smart-contracts/interact-foundry.mdx new file mode 100644 index 0000000..4c467f8 --- /dev/null +++ b/.gitbook/cn/developers-evm/smart-contracts/interact-foundry.mdx @@ -0,0 +1,136 @@ +--- +title: 使用 Foundry 与智能合约交互 +--- + +## 前置条件 + +你应该已经设置好 Foundry 项目,并成功部署了智能合约。 +请参阅[使用 Foundry 部署智能合约](./deploy-foundry/)教程了解如何操作。 + +可选但强烈推荐:你还应该已经成功验证了智能合约。 +请参阅[使用 Foundry 验证智能合约](./verify-foundry/)教程了解如何操作。 + +## 调用函数 - 查询 + +查询是只读操作。 +因此智能合约状态**不会更新**。 +由于*不需要状态更改*,不需要钱包、签名或交易费用(gas)。 + +使用以下命令查询 `value()` 函数: + +```shell +cast call \ + --rpc-url injectiveEvm \ + ${SC_ADDRESS} \ + "value()" +``` + +将 `${SC_ADDRESS}` 替换为你部署智能合约的地址。 + +例如,如果智能合约地址是 `0x213ba803265386c10ce04a2caa0f31ff3440b9cf`,命令是: + +```shell +cast call \ + --rpc-url injectiveEvm \ + 0x213ba803265386c10ce04a2caa0f31ff3440b9cf \ + "value()" +``` + +这应该输出以下内容。 + +```text +0x0000000000000000000000000000000000000000000000000000000000000000 +``` + + +请注意,`0x0000000000000000000000000000000000000000000000000000000000000000` 表示 `0`。 +它是 Solidity 的 `uint256`(智能合约中 `value()` 函数的返回类型)的十六进制原始表示。 + + +## 调用函数 - 交易 + +交易是写操作。 +因此智能合约**状态会更新**。 +由于*可能发生状态更改*,交易必须由钱包签名,并且需要支付交易费用(gas)。 + +使用以下命令执行 `increment(num)` 函数的交易。 + +```shell +cast send \ + --legacy \ + --rpc-url injectiveEvm \ + --gas-price 160000000 \ + --gas-limit 2000000 \ + --account injTest \ + ${SC_ADDRESS} \ + "increment(uint256)" \ + 1 +``` + + +请注意,gas price 以 *wei* 为单位。 +1 wei = 10^-18 INJ。 + + +将 `${SC_ADDRESS}` 替换为你部署智能合约的地址。 + +例如,如果智能合约地址是 `0x213ba803265386c10ce04a2caa0f31ff3440b9cf`,命令是: + +```shell +cast send \ + --legacy \ + --rpc-url injectiveEvm \ + --gas-price 160000000 \ + --gas-limit 2000000 \ + --account injTest \ + 0x213ba803265386c10ce04a2caa0f31ff3440b9cf \ + "increment(uint256)" \ + 1 +``` + +如果成功,这应该产生类似以下的结果: + +```text +Enter keystore password: +blockHash 0xe4c1f5faafc5365c43678135d6adc87104f0e288cddfcdffeb2f5aa08282ca22 +blockNumber 83078201 +contractAddress +cumulativeGasUsed 43623 +effectiveGasPrice 160000000 +from 0x58f936cb685Bd6a7dC9a21Fa83E8aaaF8EDD5724 +gasUsed 43623 +logs [] +logsBloom 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +root +status 1 (success) +transactionHash 0x3c95e15ba24074301323e09d09d5967cc2858e255d1fdfd912758fd8bbd353b4 +transactionIndex 0 +type 0 +blobGasPrice +blobGasUsed +to 0x213bA803265386C10CE04a2cAa0f31FF3440b9cF +``` + +更新状态后,你可以查询新状态。 +结果将反映状态更改。 + +```shell +cast call \ + --rpc-url injectiveEvm \ + ${SC_ADDRESS} \ + "value()" +``` + +这次结果应该是 `0x0000000000000000000000000000000000000000000000000000000000000001`,因为 `0 + 1 = 1`。 + +```js +0x0000000000000000000000000000000000000000000000000000000000000001 +``` + +## 下一步 + +恭喜,你已经完成了使用 Foundry 在 Injective 上开发 EVM 智能合约的整个指南! + +智能合约不能为非技术用户提供用户体验。 +为了服务他们,你需要构建一个去中心化应用。 +请查看[你的第一个 dApp](../dapps/) 指南! diff --git a/.gitbook/cn/developers-evm/smart-contracts/interact-hardhat.mdx b/.gitbook/cn/developers-evm/smart-contracts/interact-hardhat.mdx new file mode 100644 index 0000000..5cd831f --- /dev/null +++ b/.gitbook/cn/developers-evm/smart-contracts/interact-hardhat.mdx @@ -0,0 +1,118 @@ +--- +title: 使用 Hardhat 与智能合约交互 +--- + +## 前置条件 + +你应该已经设置好 Hardhat 项目,并成功部署了智能合约。 +请参阅[使用 Hardhat 部署智能合约](./deploy-hardhat/)教程了解如何操作。 + +可选但强烈推荐:你还应该已经成功验证了智能合约。 +请参阅[使用 Hardhat 验证智能合约](./verify-hardhat/)教程了解如何操作。 + +## 启动 Hardhat 控制台 + +使用以下命令启动交互式 Javascript REPL。 + +```shell +npx hardhat console --network inj_testnet +``` + +现在 shell 将是 NodeJs REPL 而不是你的常规 shell(bash、zsh 等)。 +在这个 REPL 中,我们将创建 `Counter` 智能合约的实例。 +为此,使用 `ethers.getContractFactory(...)` 和 `contract.attach('0x...');`。 +例如,如果智能合约部署到 `0x98798cc92651B1876e9Cc91EcBcfe64cac720a1b`,命令应该如下所示: + +```js +const Counter = await ethers.getContractFactory('Counter'); +const counter = await Counter.attach('0x98798cc92651B1876e9Cc91EcBcfe64cac720a1b'); +``` + +请注意,在这个 REPL 中,你会看到 `> ` 作为 shell 提示符。 +每个提示的结果输出没有这个前缀。 +因此,你的终端内容将类似于: + +```js +> const Counter = await ethers.getContractFactory('Counter'); +undefined +> const counter = await Counter.attach('0x98798cc92651B1876e9Cc91EcBcfe64cac720a1b'); +undefined +``` + +现在你可以使用 `counter` 与智能合约交互。 + +## 调用函数 - 查询 + +查询是只读操作。 +因此智能合约状态**不会更新**。 +由于*不需要状态更改*,不需要钱包、签名或交易费用(gas)。 + +使用以下命令查询 `value()` 函数。 + +```js +await counter.value(); +``` + +这应该输出以下内容。 + +```js +0n +``` + + +请注意,`0n` 表示 `0`,`n` 后缀表示它是 +[`BigInt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) +而不是 [`Number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)。 + +这是因为 Solidity 的 `uint256`(智能合约中 `value()` 函数的返回类型) +无法用 `Number` 表示, +因为其最大可能的整数值是 `2^53 - 1`。 +因此需要使用 `BigInt`。 + + +## 调用函数 - 交易 + +交易是写操作。 +因此智能合约**状态会更新**。 +由于*可能发生状态更改*,交易必须由钱包签名,并且需要支付交易费用(gas)。 + +使用以下命令执行 `increment(num)` 函数的交易。 + +```js +await counter.increment(1, { gasPrice: 160e6, gasLimit: 2e6 }); +``` + +请注意,gas price 以 *wei* 为单位。 +1 wei = 10^-18 INJ。 + + +如果成功,这应该产生类似以下的结果: + +```js +ContractTransactionResponse { ... +``` + +更新状态后,你可以查询新状态。 +结果将反映状态更改。 + +```js +await counter.value(); +``` + +这次结果应该是 `1n`,因为 `0 + 1 = 1`。 + +```js +1n +``` + +## 停止 Hardhat 控制台 + +连续按两次 `Ctrl+C`,或输入 `.exit` 命令。 + +## 下一步 + +恭喜,你已经完成了使用 Hardhat 在 Injective 上开发 EVM 智能合约的整个指南! + +智能合约不能为非技术用户提供用户体验。 +为了服务他们,你需要构建一个去中心化应用。 +请查看[你的第一个 dApp](../dapps/) 指南! diff --git a/.gitbook/cn/developers-evm/smart-contracts/test-foundry.mdx b/.gitbook/cn/developers-evm/smart-contracts/test-foundry.mdx new file mode 100644 index 0000000..3cd209a --- /dev/null +++ b/.gitbook/cn/developers-evm/smart-contracts/test-foundry.mdx @@ -0,0 +1,84 @@ +--- +title: 使用 Foundry 测试智能合约 +--- + +## 前置条件 + +你应该已经设置好 Foundry 项目,并成功编译了智能合约。 +请参阅[设置 Foundry 并编译智能合约](./compile-foundry/)教程了解如何操作。 + +## 编辑测试规范 + +由于我们测试的智能合约很简单,所需的测试用例也很简单。 + +在测试之前,我们需要部署智能合约。 +这发生在 `setUp` 块中。 +这是因为智能合约不能独立执行,它们必须在 EVM 中才能执行。 +在 Foundry 中,默认情况下,测试将在模拟的内存 EVM 实例中执行,该实例是临时的,因此部署是例行的。 + +打开文件:`test/Counter.t.sol` + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity 0.8.28; + +import { Test } from "forge-std/Test.sol"; +import { Counter } from "../src/Counter.sol"; + +contract CounterTest is Test { + Counter public counter; + + function setUp() public { + counter = new Counter(); + } + + function testInitialValue() public view { + assertEq(counter.value(), 0); + } + + function testIncrementValueFromZero() public { + counter.increment(100); + assertEq(counter.value(), 100); + } + + function testIncrementValueFromNonZero() public { + counter.increment(100); + counter.increment(23); + assertEq(counter.value(), 123); + } +} + +``` + +我们看到有 3 个测试用例: + +- 检查初始 `value()`。 +- 调用 `increment(num)` 然后检查 `value()` 是否已更新。 +- 再次调用 `increment(num)`,然后检查 `value()` 是否再次更新。 + +## 对智能合约执行测试 + +以下命令运行我们刚才查看的测试。 + +```shell +forge test +``` + +## 检查测试输出 + +如果所有测试都按计划工作,你应该看到类似以下的输出: + +```text +Ran 3 tests for test/Counter.t.sol:CounterTest +[PASS] testIncrementValueFromNonZero() (gas: 32298) +[PASS] testIncrementValueFromZero() (gas: 31329) +[PASS] testInitialValue() (gas: 10392) +Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 5.35ms (3.16ms CPU time) + +Ran 1 test suite in 171.04ms (5.35ms CPU time): 3 tests passed, 0 failed, 0 skipped (3 total tests) +``` + +## 下一步 + +现在你已经测试了智能合约,你可以开始部署该智能合约了! +接下来请查看[使用 Foundry 部署智能合约](./deploy-foundry/)教程。 diff --git a/.gitbook/cn/developers-evm/smart-contracts/test-hardhat.mdx b/.gitbook/cn/developers-evm/smart-contracts/test-hardhat.mdx new file mode 100644 index 0000000..990a0a8 --- /dev/null +++ b/.gitbook/cn/developers-evm/smart-contracts/test-hardhat.mdx @@ -0,0 +1,89 @@ +--- +title: 使用 Hardhat 测试智能合约 +--- + +## 前置条件 + +你应该已经设置好 Hardhat 项目,并成功编译了智能合约。 +请参阅[设置 Hardhat 并编译智能合约](./compile-hardhat/)教程了解如何操作。 + +## 编辑测试规范 + +由于我们测试的智能合约很简单,所需的测试用例也很简单。 + +在测试之前,我们需要部署智能合约。 +这发生在 `before` 块中。 +这是因为智能合约不能独立执行,它们必须在 EVM 中才能执行。 +在 Hardhat 中,默认情况下,测试将在模拟的内存 EVM 实例中执行,该实例是临时的,因此部署是例行的。 + +打开文件:`test/Counter.test.js` + +```js +const { expect } = require('chai'); + +describe('Counter', function () { + let counter; + + before(async function () { + Counter = await ethers.getContractFactory('Counter'); + counter = await Counter.deploy(); + await counter.waitForDeployment(); + }); + + it('should start with a count of 0', async function () { + expect(await counter.value()).to.equal(0); + }); + + it('should increment the count starting from zero', async function () { + await counter.increment(100); + expect(await counter.value()).to.equal(100); + }); + + it('should increment the count starting from non-zero', async function () { + await counter.increment(23); + expect(await counter.value()).to.equal(123); + }); +}); + +``` + +我们看到有 3 个测试用例: + +- 检查初始 `value()`。 +- 调用 `increment(num)` 然后检查 `value()` 是否已更新。 +- 再次调用 `increment(num)`,然后检查 `value()` 是否再次更新。 + +## 对智能合约执行测试 + +以下命令运行我们刚才查看的测试。 + +```shell +npx hardhat test +``` + +以下命令运行测试,但**不是**在模拟的 EVM 实例中。 +相反,智能合约被部署到 Injective Testnet(公共网络),然后针对它运行测试。 +在大多数情况下**不推荐**这样做,仅在特定/高级用例中需要。 + +```shell +npx hardhat test --network inj_testnet +``` + +## 检查测试输出 + +如果所有测试都按计划工作,你应该看到类似以下的输出: + +```text + Counter + ✔ should start with a count of 0 + ✔ should increment the count starting from zero + ✔ should increment the count starting from non-zero + 3 passing (41ms) +``` + +之后是一个表格,其中包含有关 gas 的额外报告,这是复杂性和交易成本的衡量标准。 + +## 下一步 + +现在你已经测试了智能合约,你可以开始部署该智能合约了! +接下来请查看[使用 Hardhat 部署智能合约](./deploy-hardhat/)教程。 diff --git a/.gitbook/cn/developers-evm/smart-contracts/verify-foundry.mdx b/.gitbook/cn/developers-evm/smart-contracts/verify-foundry.mdx new file mode 100644 index 0000000..d54ac39 --- /dev/null +++ b/.gitbook/cn/developers-evm/smart-contracts/verify-foundry.mdx @@ -0,0 +1,80 @@ +--- +title: 使用 Foundry 验证智能合约 +--- + +## 前置条件 + +你应该已经设置好 Foundry 项目,并成功部署了智能合约。 +请参阅[使用 Foundry 部署智能合约](./deploy-foundry/)教程了解如何操作。 + +## 什么是智能合约验证? + +验证过程不会对智能合约本身或网络的任何其他状态产生任何影响。 + +相反,它是一个标准化的过程,通过该过程向网络浏览器提供部署在特定地址的智能合约的原始源代码。网络浏览器**独立编译**该源代码,并验证生成的 bytecode 确实与智能合约部署交易中存在的 bytecode **匹配**。 + +如果验证通过(存在匹配),区块浏览器会为该特定智能合约的页面"解锁"增强模式。 +现在会显示更多智能合约详情,包括: +* 完整源代码(Solidity) +* ABI(JSON) +* 交易和事件以更高的详细程度显示(使用 ABI 解析) + +此外,如果用户连接他们的钱包,他们可以直接在网络浏览器中调用函数来查询智能合约,甚至发送交易来更新其状态。 + +{/* TODO consider moving this section to FAQs */} + +## 运行验证命令 + +输入以下命令: + +```shell +forge verify-contract \ + --rpc-url injectiveEvm \ + --verifier blockscout \ + --verifier-url 'https://testnet.blockscout-api.injective.network/api/' \ + ${SC_ADDRESS} \ + src/Counter.sol:Counter +``` + +将 `${SC_ADDRESS}` 替换为你部署智能合约的地址。 + +例如,如果智能合约地址是 `0x213bA803265386C10CE04a2cAa0f31FF3440b9cF`,命令是: + +```shell +forge verify-contract \ + --rpc-url injectiveEvm \ + --verifier blockscout \ + --verifier-url 'https://testnet.blockscout-api.injective.network/api/' \ + 0x213bA803265386C10CE04a2cAa0f31FF3440b9cF \ + src/Counter.sol:Counter +``` + +## 检查验证结果 + +你应该在终端中看到类似以下的输出: + +```text +Start verifying contract `0x213bA803265386C10CE04a2cAa0f31FF3440b9cF` deployed on 1439 +Submitting verification for [src/Counter.sol:Counter] 0x213bA803265386C10CE04a2cAa0f31FF3440b9cF. +Submitted contract for verification: + Response: `OK` + GUID: `213ba803265386c10ce04a2caa0f31ff3440b9cf686b778c` + URL: https://testnet.blockscout-api.injective.network/address/0x213ba803265386c10ce04a2caa0f31ff3440b9cf +``` + +更有趣的结果是访问网络浏览器。 +访问验证输出中的网络浏览器 URL。 +然后选择 "Contract" 标签。 +然后选择 "Code" 子标签。 +之前只有 "ByteCode" 可用, +现在 "Code"、"Compiler" 和 "ABI" 也可用了。 + +仍然在 "Contract" 标签中, +选择 "Read/Write contract" 子标签。 +之前这不存在, +但现在你可以直接从区块浏览器与每个智能合约函数交互。 + +## 下一步 + +现在你已经部署并验证了智能合约,你可以开始与该智能合约交互了! +接下来请查看[使用 Foundry 与智能合约交互](./interact-foundry/)教程。 diff --git a/.gitbook/cn/developers-evm/smart-contracts/verify-hardhat.mdx b/.gitbook/cn/developers-evm/smart-contracts/verify-hardhat.mdx new file mode 100644 index 0000000..3e30a30 --- /dev/null +++ b/.gitbook/cn/developers-evm/smart-contracts/verify-hardhat.mdx @@ -0,0 +1,100 @@ +--- +title: 使用 Hardhat 验证智能合约 +--- + +## 前置条件 + +你应该已经设置好 Hardhat 项目,并成功部署了智能合约。 +请参阅[使用 Hardhat 部署智能合约](./deploy-hardhat/)教程了解如何操作。 + +## 什么是智能合约验证? + +验证过程不会对智能合约本身或网络的任何其他状态产生任何影响。 + +相反,它是一个标准化的过程,通过该过程向网络浏览器提供部署在特定地址的智能合约的原始源代码。网络浏览器**独立编译**该源代码,并验证生成的 bytecode 确实与智能合约部署交易中存在的 bytecode **匹配**。 + +如果验证通过(存在匹配),区块浏览器会为该特定智能合约的页面"解锁"增强模式。 +现在会显示更多智能合约详情,包括: +* 完整源代码(Solidity) +* ABI(JSON) +* 交易和事件以更高的详细程度显示(使用 ABI 解析) + +此外,如果用户连接他们的钱包,他们可以直接在网络浏览器中调用函数来查询智能合约,甚至发送交易来更新其状态。 + +{/* TODO consider moving this section to FAQs */} + +## 编辑智能合约验证配置 + +打开 `hardhat.config.js`,查看 `etherscan` 和 `sourcify` 元素。 + +```js + etherscan: { + apiKey: { + inj_testnet: 'nil', + }, + customChains: [ + { + network: 'inj_testnet', + chainId: 1439, + urls: { + apiURL: 'https://testnet.blockscout-api.injective.network/api', + browserURL: 'https://testnet.blockscout.injective.network/', + }, + }, + ], + }, + sourcify: { + enabled: false, + }, +``` + +Sourcify 和 Etherscan 是两个流行的区块浏览器,每个都有不同的验证 API。 +Injective 使用 Blockscout,它与 Etherscan API 兼容。 +因此,配置中禁用了 Sourcify。 +在 Etherscan 配置中,不需要 `apiKey` 值,所以任何非空值都可以。 +`customChains` 中的 `inj_testnet` 网络已配置了适用于 Injective Testnet 的适当值。 + +## 运行验证命令 + +输入以下命令: + +```shell +npx hardhat verify --network inj_testnet ${SC_ADDRESS} +``` + +将 `${SC_ADDRESS}` 替换为你部署智能合约的地址。 + +例如,如果智能合约地址是 `0x98798cc92651B1876e9Cc91EcBcfe64cac720a1b`,命令是: + +```shell +npx hardhat verify --network inj_testnet 0x98798cc92651B1876e9Cc91EcBcfe64cac720a1b +``` + +## 检查验证结果 + +你应该在终端中看到类似以下的输出: + +```text +Successfully submitted source code for contract +contracts/Counter.sol:Counter at 0x98798cc92651B1876e9Cc91EcBcfe64cac720a1b +for verification on the block explorer. Waiting for verification result... + +Successfully verified contract Counter on the block explorer. +https://testnet.blockscout.injective.network/address/0x98798cc92651B1876e9Cc91EcBcfe64cac720a1b#code +``` + +更有趣的结果是访问网络浏览器。 +访问验证输出中的网络浏览器 URL。 +然后选择 "Contract" 标签。 +然后选择 "Code" 子标签。 +之前只有 "ByteCode" 可用,现在 "Code"、"Compiler" 和 "ABI" 也可用了。 + +仍然在 "Contract" 标签中, +选择 "Read/Write contract" 子标签。 +之前这不存在, +但现在你可以直接从区块浏览器与每个智能合约函数交互。 + +## 下一步 + +现在你已经部署并验证了智能合约,你可以开始与该智能合约交互了! +接下来请查看[使用 Hardhat 与智能合约交互](./interact-hardhat/)教程。 diff --git a/.gitbook/cn/developers-evm/wrapped-inj.mdx b/.gitbook/cn/developers-evm/wrapped-inj.mdx new file mode 100644 index 0000000..dd85d53 --- /dev/null +++ b/.gitbook/cn/developers-evm/wrapped-inj.mdx @@ -0,0 +1,124 @@ +--- +title: Wrapped INJ (wINJ) +--- + +# Wrapped INJ (wINJ) + +## 什么是 wrapped 加密货币? + +在 Injective 上,INJ 是加密货币,用于支付网络上的交易费用。 + +然而,一些 dApp(包括 DEX)在其界面中只接受 ERC20 token,因此 INJ **不能**与它们一起使用。 + +解决方案是创建一个包装 INJ 的 ERC20 token,称为 "wrapped INJ"。 +其 token 符号是 **wINJ**。 +因此,任何接受 ERC20 token 的 dApp 都接受 wINJ。 + +wINJ token 的工作机制很简单: + +- Mint:每当向其存入 INJ 时增加总供应量。 +- Burn:每当从中提取 INJ 时减少总供应量。 + +你可以将 wINJ 视为与 INJ 1:1 抵押的 ERC20 token,因此可以被视为等值但具有不同的技术接口。 + +## wINJ 与 wETH 相同吗? + +对于熟悉 Ethereum 的人来说, +你可能会认为这听起来与 wrapped Ether (wETH) 相同。 +你是对的,到目前为止 wINJ 的行为方式与 wETH 相同。 + +然而,请注意 Injective 网络采用 MultiVM 技术架构设计。 +这意味着如果 wINJ 使用*标准* ERC20 实现, +就像 wETH 那样,wINJ 在与 +Injective 网络的非 EVM 部分(例如 Cosmos 交易)交互时将**无法**访问。 + +这正是 Injective 的 +[MultiVM Token Standard (MTS)](/cn/developers-evm/multivm-token-standard) +设计的目的。 + +具体来说,请注意 +[这一行](https://github.com/InjectiveLabs/solidity-contracts/blob/b152129a/src/WINJ9.sol#L9C10-L9C15): + +```solidity +contract WINJ9 is BankERC20, IWINJ9 { +``` + +wINJ 智能合约不是像典型的 ERC20 实现那样将余额存储为智能合约中的 `uint256` 值, +而是使用 `Bank` precompile。 +魔法发生在 +[`BankERC20` 的 `_update` 函数](https://github.com/InjectiveLabs/solidity-contracts/blob/b152129a/src/BankERC20.sol#L50-L81)中, +其中通过其 [EVM precompile](/cn/developers-evm/bank-precompile "Injective 原生 Bank 模块的 EVM precompile") 调用 `Bank` 模块中的 `mint`、`burn` 或 `transfer` 函数。 + +由于这些余额从 `Bank` precompile 存储/检索, +它们可以从 Injective 的 MultiVM 架构中的其他地方访问。 +例如,使用 Cosmos SDK 你可以查询 wINJ 余额, +即使在通过 EVM 交易更新它们之后; +反之亦然。 +我们将此称为"原生链余额"。 + +查看 [wINJ 的完整演示](https://github.com/InjectiveLabs/solidity-contracts/tree/master/demos/winj9)。 + +## 如何以编程方式使用 wINJ + +- Injective Mainnet 上的地址: `0x0000000088827d2d103ee2d9A6b781773AE03FfB` +- Injective Testnet 上的地址: `0x0000000088827d2d103ee2d9A6b781773AE03FfB` + +要将 INJ 转换为 wINJ,在此智能合约上调用 `deposit` 函数: + +- 函数签名是: `deposit() public payable` +- 请注意,你不需要将金额指定为参数, + 而是在交易上设置 `value`,`payable` 将其作为 `msg.value` 获取。 + +要将 wINJ 转换为 INJ,在此智能合约上调用 `withdraw` 函数: + +- 函数签名是: `withdraw(uint256 wad) public` +- 将你打算接收的 INJ 金额设置为 `wad` 参数。 + +所有其他函数,例如转账,与标准 ERC20 相同。 + +## 如何通过网络浏览器使用 wINJ + +- Injective Mainnet 的 Explorer URL: [`0x0000000088827d2d103ee2d9A6b781773AE03FfB`](https://blockscout.injective.network/address/0x0000000088827d2d103ee2d9A6b781773AE03FfB?tab=contract) +- Injective Testnet 的 Explorer URL: [`0x0000000088827d2d103ee2d9A6b781773AE03FfB`](https://testnet.blockscout.injective.network/address/0x0000000088827d2d103ee2d9A6b781773AE03FfB?tab=contract) + +要将 INJ 转换为 wINJ,在此智能合约上调用 `deposit` 函数: + +- 在 wINJ token 的浏览器页面中导航到 "Contract" 标签,然后是 "Read/Write contract" 子标签。 +- 找到 `deposit()` 函数,点击 `>` 符号展开它 +- 在 "Send native INJ (uint256)" 字段中填写你希望转换的 INJ 金额 + - 请注意,此数字会自动乘以 `10^18`,你不需要手动执行该转换 +- 按 "Write" 按钮 +- 在你的钱包中,确认交易以签名并提交。 +- 你的钱包应该反映 INJ 减少和 wINJ 增加你选择的金额。 + - 请注意,INJ 减少会略多一些,因为它用于支付交易费用。 + +要将 wINJ 转换为 INJ,在此智能合约上调用 `withdraw` 函数: + +- 在 wINJ token 的浏览器页面中导航到 "Contract" 标签,然后是 "Read/Write contract" 子标签。 +- 找到 `withdraw()` 函数,点击 `>` 符号展开它 +- 在 "wad (uint256)" 字段中填写你希望转换的 wINJ 金额 + - 请注意,此数字会自动乘以 `10^18`,你不需要手动执行该转换 +- 按 "Write" 按钮 +- 在你的钱包中,确认交易以签名并提交。 +- 你的钱包应该反映 INJ 增加和 wINJ 减少你选择的金额。 + - 请注意,INJ 增加会略少一些,因为它用于支付交易费用。 + +# 如何通过 Injective Do 使用 wINJ + +- 访问 [Injective Do](https://do.injective.network/) +- 按右上角的 "Connect" 按钮 +- 选择你的钱包 +- 在你的钱包中选择 "Allow" 以允许它连接到 Injective Do dApp。 +- 你现在应该看到你的钱包地址出现在右上角(之前 "Connect" 按钮的位置) +- 在顶部的导航栏中,选择 "EVM" +- 在下拉菜单中选择 "Wrap/Unwrap" +- 要将 INJ 转换为 wINJ + - 按顶部的 "Wrap" 标签 + - 在 "Amount" 字段中,输入你想要转换的金额 + - 按底部的 "Wrap" 按钮 + - 交易完成后,在你的钱包中检查你的 INJ 和 wINJ 余额 +- 要将 wINJ 转换为 INJ + - 按顶部的 "Unwrap" 标签 + - 在 "Amount" 字段中,输入你想要转换的金额 + - 按底部的 "Unwrap" 按钮 + - 交易完成后,在你的钱包中检查你的 INJ 和 wINJ 余额 diff --git a/.gitbook/docs.json b/.gitbook/docs.json index a3eb99e..58fc796 100644 --- a/.gitbook/docs.json +++ b/.gitbook/docs.json @@ -13,9 +13,12 @@ }, "favicon": "/img/injective-logo-192x192.png", "navigation": { - "groups": [ + "languages": [ { - "group": "INJECTIVE", + "language": "en", + "groups": [ + { + "group": "INJECTIVE", "pages": [ "index", { @@ -636,6 +639,57 @@ "references" ] } + ] + }, + { + "language": "cn", + "groups": [ + { + "group": "EVM 开发者", + "icon": "rectangle-code", + "expanded": false, + "pages": [ + "cn/developers-evm/index", + "cn/developers-evm/network-information", + { + "group": "你的第一个 EVM 智能合约", + "pages": [ + "cn/developers-evm/smart-contracts/index", + "cn/developers-evm/smart-contracts/compile-hardhat", + "cn/developers-evm/smart-contracts/test-hardhat", + "cn/developers-evm/smart-contracts/deploy-hardhat", + "cn/developers-evm/smart-contracts/verify-hardhat", + "cn/developers-evm/smart-contracts/interact-hardhat", + "cn/developers-evm/smart-contracts/compile-foundry", + "cn/developers-evm/smart-contracts/test-foundry", + "cn/developers-evm/smart-contracts/deploy-foundry", + "cn/developers-evm/smart-contracts/verify-foundry", + "cn/developers-evm/smart-contracts/interact-foundry" + ] + }, + { + "group": "你的第一个 EVM dApp", + "pages": [ + "cn/developers-evm/dapps/index", + "cn/developers-evm/dapps/connect-with-metamask", + "cn/developers-evm/dapps/connect-with-walletconnect" + ] + }, + "cn/developers-evm/evm-equivalence", + "cn/developers-evm/multivm-token-standard", + "cn/developers-evm/wrapped-inj", + "cn/developers-evm/precompiles", + "cn/developers-evm/bank-precompile", + "cn/developers-evm/exchange-precompile", + "cn/developers-evm/erc20-module", + "cn/developers-evm/infrastructure-and-tooling", + "cn/developers-evm/add-injective-to-your-dapp", + "cn/developers-evm/evm-integrations-cheat-sheet", + "cn/developers-evm/evm-integrations-faq" + ] + } + ] + } ] }, "styling": {