441 lines
9.8 KiB
Markdown
441 lines
9.8 KiB
Markdown
# NAC以太坊桥插件
|
||
|
||
**版本**: v0.3.0
|
||
**状态**: Phase 3完成 - 以太坊桥插件原型
|
||
|
||
---
|
||
|
||
## 📦 功能概述
|
||
|
||
NAC以太坊桥插件是第一个具体的跨链桥实现,支持NAC钱包与以太坊主网/测试网的跨链资产转移。
|
||
|
||
### 核心特性
|
||
|
||
- ✅ **Web3集成**: 基于ethers-rs的完整Web3功能
|
||
- ✅ **ETH余额查询**: 查询任意地址的ETH余额
|
||
- ✅ **ERC-20余额查询**: 支持所有标准ERC-20 Token
|
||
- ✅ **锁定交易构造**: ETH和ERC-20锁定交易数据生成
|
||
- ✅ **交易收据查询**: 获取交易确认和日志
|
||
- ✅ **SPV证明**: Merkle树证明生成和验证
|
||
- ✅ **常见Token**: 内置USDT/USDC/DAI/WBTC支持
|
||
|
||
---
|
||
|
||
## 🏗️ 模块结构
|
||
|
||
```
|
||
nac-bridge-ethereum/
|
||
├── src/
|
||
│ ├── lib.rs # 主模块
|
||
│ ├── ethereum_bridge.rs # 以太坊桥插件实现
|
||
│ ├── erc20.rs # ERC-20 Token辅助
|
||
│ └── spv.rs # SPV证明验证
|
||
├── Cargo.toml
|
||
└── README.md
|
||
```
|
||
|
||
---
|
||
|
||
## 🔧 核心API
|
||
|
||
### EthereumBridgePlugin
|
||
|
||
```rust
|
||
pub struct EthereumBridgePlugin {
|
||
chain_id: u64,
|
||
provider: Arc<Provider<Http>>,
|
||
bridge_contract_address: String,
|
||
chain_name: String,
|
||
}
|
||
|
||
impl EthereumBridgePlugin {
|
||
// 创建新的以太坊桥插件
|
||
pub async fn new(
|
||
rpc_url: &str,
|
||
chain_id: u64,
|
||
bridge_contract_address: String,
|
||
) -> Result<Self, BridgeError>;
|
||
|
||
// 获取ETH余额
|
||
pub async fn get_eth_balance(&self, address: &str) -> Result<u128, BridgeError>;
|
||
|
||
// 获取ERC-20余额
|
||
pub async fn get_erc20_balance(
|
||
&self,
|
||
user_address: &str,
|
||
token_address: &str,
|
||
) -> Result<u128, BridgeError>;
|
||
|
||
// 获取余额(自动判断ETH或ERC-20)
|
||
pub async fn get_balance(
|
||
&self,
|
||
address: &str,
|
||
token: &TokenInfo,
|
||
) -> Result<u128, BridgeError>;
|
||
|
||
// 构造锁定ETH交易数据
|
||
pub fn build_lock_eth_tx_data(
|
||
&self,
|
||
amount: u128,
|
||
nac_target_address: &[u8; 32],
|
||
) -> Vec<u8>;
|
||
|
||
// 构造锁定ERC-20交易数据
|
||
pub fn build_lock_erc20_tx_data(
|
||
&self,
|
||
token_address: &str,
|
||
amount: u128,
|
||
nac_target_address: &[u8; 32],
|
||
) -> Result<Vec<u8>, BridgeError>;
|
||
|
||
// 获取交易收据
|
||
pub async fn get_transaction_receipt(
|
||
&self,
|
||
tx_hash: &str,
|
||
) -> Result<TransactionReceipt, BridgeError>;
|
||
|
||
// 获取区块信息
|
||
pub async fn get_block(&self, block_number: u64) -> Result<Block<H256>, BridgeError>;
|
||
}
|
||
```
|
||
|
||
### SPVProofVerifier
|
||
|
||
```rust
|
||
pub struct SPVProofVerifier;
|
||
|
||
impl SPVProofVerifier {
|
||
// 创建新的SPV证明验证器
|
||
pub fn new() -> Self;
|
||
|
||
// 验证Merkle证明
|
||
pub fn verify_merkle_proof(
|
||
&self,
|
||
tx_hash: &[u8],
|
||
proof: &MerkleProof,
|
||
) -> bool;
|
||
|
||
// 生成Merkle证明
|
||
pub fn generate_merkle_proof(
|
||
&self,
|
||
tx_hashes: &[Vec<u8>],
|
||
tx_index: usize,
|
||
) -> Option<MerkleProof>;
|
||
|
||
// 验证区块头
|
||
pub fn verify_block_header(
|
||
&self,
|
||
block_header: &[u8],
|
||
expected_hash: &[u8],
|
||
) -> bool;
|
||
}
|
||
```
|
||
|
||
### ERC20Token
|
||
|
||
```rust
|
||
pub struct ERC20Token {
|
||
pub address: String,
|
||
pub symbol: String,
|
||
pub name: String,
|
||
pub decimals: u8,
|
||
pub total_supply: Option<u128>,
|
||
}
|
||
|
||
impl ERC20Token {
|
||
// 创建新的ERC-20 Token
|
||
pub fn new(
|
||
address: String,
|
||
symbol: String,
|
||
name: String,
|
||
decimals: u8,
|
||
) -> Self;
|
||
|
||
// 常见的ERC-20 Token列表
|
||
pub fn common_tokens() -> Vec<ERC20Token>;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🚀 使用示例
|
||
|
||
### 1. 创建以太坊桥插件
|
||
|
||
```rust
|
||
use nac_bridge_ethereum::EthereumBridgePlugin;
|
||
|
||
#[tokio::main]
|
||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||
// 连接到以太坊主网
|
||
let bridge = EthereumBridgePlugin::new(
|
||
"https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY",
|
||
1, // 主网链ID
|
||
"0x1234567890123456789012345678901234567890".to_string(),
|
||
).await?;
|
||
|
||
println!("Connected to {}", bridge.chain_name());
|
||
|
||
Ok(())
|
||
}
|
||
```
|
||
|
||
### 2. 查询ETH余额
|
||
|
||
```rust
|
||
let address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"; // Vitalik's address
|
||
let balance = bridge.get_eth_balance(address).await?;
|
||
|
||
println!("ETH Balance: {} wei", balance);
|
||
println!("ETH Balance: {} ETH", balance as f64 / 1e18);
|
||
```
|
||
|
||
### 3. 查询ERC-20余额
|
||
|
||
```rust
|
||
use nac_bridge_ethereum::{EthereumBridgePlugin, TokenInfo};
|
||
|
||
let user_address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045";
|
||
let usdt_address = "0xdac17f958d2ee523a2206206994597c13d831ec7";
|
||
|
||
let balance = bridge.get_erc20_balance(user_address, usdt_address).await?;
|
||
|
||
println!("USDT Balance: {} (6 decimals)", balance);
|
||
```
|
||
|
||
### 4. 构造锁定ETH交易
|
||
|
||
```rust
|
||
// NAC目标地址(32字节)
|
||
let nac_address = [0x01; 32];
|
||
|
||
// 锁定1 ETH
|
||
let amount = 1_000_000_000_000_000_000u128; // 1 ETH in wei
|
||
|
||
// 构造交易数据
|
||
let tx_data = bridge.build_lock_eth_tx_data(amount, &nac_address);
|
||
|
||
println!("Transaction data: 0x{}", hex::encode(&tx_data));
|
||
|
||
// 用户需要用自己的钱包签名并广播这个交易
|
||
```
|
||
|
||
### 5. 构造锁定ERC-20交易
|
||
|
||
```rust
|
||
let usdt_address = "0xdac17f958d2ee523a2206206994597c13d831ec7";
|
||
let amount = 1_000_000u128; // 1 USDT (6 decimals)
|
||
let nac_address = [0x01; 32];
|
||
|
||
let tx_data = bridge.build_lock_erc20_tx_data(
|
||
usdt_address,
|
||
amount,
|
||
&nac_address,
|
||
)?;
|
||
|
||
println!("Transaction data: 0x{}", hex::encode(&tx_data));
|
||
```
|
||
|
||
### 6. 验证SPV证明
|
||
|
||
```rust
|
||
use nac_bridge_ethereum::SPVProofVerifier;
|
||
|
||
let verifier = SPVProofVerifier::new();
|
||
|
||
// 假设我们有4个交易
|
||
let tx_hashes: Vec<Vec<u8>> = vec![
|
||
vec![1, 2, 3, 4],
|
||
vec![5, 6, 7, 8],
|
||
vec![9, 10, 11, 12],
|
||
vec![13, 14, 15, 16],
|
||
];
|
||
|
||
// 为第2个交易生成Merkle证明
|
||
let proof = verifier.generate_merkle_proof(&tx_hashes, 1).unwrap();
|
||
|
||
// 验证证明
|
||
let is_valid = verifier.verify_merkle_proof(&tx_hashes[1], &proof);
|
||
assert!(is_valid);
|
||
|
||
println!("Merkle proof is valid!");
|
||
```
|
||
|
||
### 7. 使用常见Token列表
|
||
|
||
```rust
|
||
use nac_bridge_ethereum::ERC20Token;
|
||
|
||
let tokens = ERC20Token::common_tokens();
|
||
|
||
for token in tokens {
|
||
println!("{} ({}) - {} decimals", token.name, token.symbol, token.decimals);
|
||
println!(" Address: {}", token.address);
|
||
}
|
||
|
||
// 输出:
|
||
// Tether USD (USDT) - 6 decimals
|
||
// Address: 0xdac17f958d2ee523a2206206994597c13d831ec7
|
||
// USD Coin (USDC) - 6 decimals
|
||
// Address: 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
|
||
// Dai Stablecoin (DAI) - 18 decimals
|
||
// Address: 0x6b175474e89094c44da98b954eedeac495271d0f
|
||
// Wrapped BTC (WBTC) - 8 decimals
|
||
// Address: 0x2260fac5e5542a773aa44fbcfedf7c193bc2c599
|
||
```
|
||
|
||
---
|
||
|
||
## 🧪 测试
|
||
|
||
```bash
|
||
cargo test
|
||
```
|
||
|
||
测试结果:
|
||
```
|
||
running 6 tests
|
||
test ethereum_bridge::tests::test_ethereum_bridge_creation ... ignored
|
||
test erc20::tests::test_erc20_token_creation ... ok
|
||
test erc20::tests::test_common_tokens ... ok
|
||
test spv::tests::test_block_header_verification ... ok
|
||
test spv::tests::test_merkle_proof_generation_and_verification ... ok
|
||
test ethereum_bridge::tests::test_build_lock_eth_tx_data ... ok
|
||
|
||
test result: ok. 5 passed; 0 failed; 1 ignored
|
||
```
|
||
|
||
**注意**: `test_ethereum_bridge_creation`测试需要实际的RPC节点,因此被标记为`#[ignore]`。
|
||
|
||
---
|
||
|
||
## 📋 支持的链
|
||
|
||
| 链ID | 链名称 | 状态 |
|
||
|------|--------|------|
|
||
| 1 | Ethereum Mainnet | ✅ 支持 |
|
||
| 5 | Goerli Testnet | ✅ 支持 |
|
||
| 11155111 | Sepolia Testnet | ✅ 支持 |
|
||
|
||
---
|
||
|
||
## 📊 技术实现
|
||
|
||
### 1. Web3集成
|
||
|
||
使用`ethers-rs`库实现完整的Web3功能:
|
||
|
||
- **Provider**: HTTP RPC提供商
|
||
- **Transaction**: 交易构造和签名
|
||
- **Contract**: 智能合约调用
|
||
- **Types**: 以太坊类型(Address, U256, H256等)
|
||
|
||
### 2. ERC-20余额查询
|
||
|
||
通过`eth_call`调用ERC-20合约的`balanceOf`函数:
|
||
|
||
```rust
|
||
// balanceOf(address) -> uint256
|
||
let selector = 0x70a08231;
|
||
let data = [selector, padded_address];
|
||
let result = provider.call(tx, None).await?;
|
||
let balance = U256::from_big_endian(&result);
|
||
```
|
||
|
||
### 3. SPV证明
|
||
|
||
实现简化的SPV(Simplified Payment Verification)证明:
|
||
|
||
- **Merkle树构建**: 从交易哈希构建Merkle树
|
||
- **Merkle路径**: 生成从叶子到根的证明路径
|
||
- **验证**: 沿着路径重新计算哈希,验证根哈希
|
||
|
||
### 4. 交易数据构造
|
||
|
||
构造符合以太坊ABI规范的交易数据:
|
||
|
||
```
|
||
函数选择器(4字节) + 参数编码(32字节对齐)
|
||
```
|
||
|
||
---
|
||
|
||
## 🔒 安全特性
|
||
|
||
### 已实现
|
||
|
||
- ✅ 地址格式验证
|
||
- ✅ 交易哈希验证
|
||
- ✅ Merkle证明验证
|
||
- ✅ 错误处理和类型安全
|
||
|
||
### 待实现(后续Phase)
|
||
|
||
- [ ] 交易签名验证
|
||
- [ ] Gas估算优化
|
||
- [ ] 重放攻击防护
|
||
- [ ] 多签验证
|
||
|
||
---
|
||
|
||
## 🚀 下一步计划
|
||
|
||
### Phase 4: 桥合约交互
|
||
|
||
1. **智能合约部署**
|
||
- 编写Charter桥合约(NAC侧)
|
||
- 部署到NAC测试网
|
||
- 合约接口绑定
|
||
|
||
2. **事件监听**
|
||
- 监听锁定事件
|
||
- 解析事件日志
|
||
- 触发中继操作
|
||
|
||
3. **合约调用**
|
||
- 锁定资产
|
||
- 解锁资产
|
||
- 查询状态
|
||
|
||
### Phase 5: 完整跨链流程
|
||
|
||
1. **NAC → 以太坊**
|
||
- 用户在NAC销毁包裹资产
|
||
- 中继节点验证
|
||
- 以太坊桥合约解锁原资产
|
||
|
||
2. **以太坊 → NAC**
|
||
- 用户在以太坊锁定资产
|
||
- 中继节点监听事件
|
||
- NAC铸造包裹资产
|
||
|
||
---
|
||
|
||
## 📖 依赖库
|
||
|
||
| 库 | 版本 | 用途 |
|
||
|---|------|------|
|
||
| ethers | 2.0 | Web3功能 |
|
||
| tokio | 1.0 | 异步运行时 |
|
||
| async-trait | 0.1 | 异步trait |
|
||
| serde | 1.0 | 序列化 |
|
||
| sha3 | 0.10 | Keccak256哈希 |
|
||
| hex | 0.4 | 十六进制编码 |
|
||
| thiserror | 1.0 | 错误处理 |
|
||
|
||
---
|
||
|
||
## 📄 许可证
|
||
|
||
Copyright © 2026 NAC Wallet Team
|
||
All rights reserved.
|
||
|
||
---
|
||
|
||
## 📞 联系方式
|
||
|
||
**开发团队**: NAC Wallet Team
|
||
**项目地址**: `/home/ubuntu/NAC_Clean_Dev/nac-bridge-ethereum`
|
||
**版本**: v0.3.0
|
||
**状态**: ✅ Phase 3完成
|