从代码实例看 Move、Solidity 和 Rust 在应对重入攻击的差异

一、Solidity 的重入攻击代码实例 (一)存在重入漏洞的 Solidity 计数器合约

js 复制代码
pragma solidity ^0.8.0;

contract ReentrantCounter {
    uint256 public balance;

    constructor() {
        balance = 0;
    }

    function deposit() public payable {
        balance += msg.value;
    }

    function withdraw() public {
        require(balance >= msg.value, "Insufficient balance");
        (bool success, ) = msg.sender.call{value: msg.value}("");
        require(success, "Transfer failed");
        balance -= msg.value;
    }
}

contract AttackContract {
    ReentrantCounter target;

    constructor(ReentrantCounter _target) {
        target = _target;
    }

    fallback() external payable {
        if (address(target).balance >= msg.value) {
            target.withdraw();
        }
    }

    function attack() public payable {
        target.deposit{value: msg.value}();
        target.withdraw();
    }
}

(二)重入攻击原理分析 在上述 Solidity 代码中,ReentrantCounter合约实现了一个简单的存款和取款功能。withdraw函数中,在向外部地址发送以太币后,才更新balance变量。AttackContract合约利用这一点,在fallback函数中反复调用target.withdraw(),只要ReentrantCounter合约还有余额,就能持续取款,导致ReentrantCounter合约的balance出现负数,造成资金损失。 二、Move 语言实现的计数器合约

js 复制代码
module counter {
    struct Counter has key {
        value: u64
    }

    public fun deposit(account: &signer, amount: u64) {
        let counter = borrow_global_mut<Counter>(account);
        counter.value = counter.value + amount;
    }

    public fun withdraw(account: &signer, amount: u64) {
        let counter = borrow_global_mut<Counter>(account);
        assert!(counter.value >= amount, 0);
        counter.value = counter.value - amount;
    }

    public entry fun init(account: &signer) {
        assert!(!exists<Counter>(account), 0);
        move_to(account, Counter { value: 0 });
    }
}

(一)Move 避免重入攻击的原理 Move 语言通过资源管理和线性逻辑来避免重入攻击。在 Move 中,资源是 "一等公民",Counter结构体作为资源,其操作遵循严格的规则。在withdraw函数中,先检查余额足够后直接扣除余额,不存在像 Solidity 那样先进行外部操作再更新状态的情况。而且 Move 的资源不能被复制,同一时间只能被一个操作访问,这从根本上杜绝了重入攻击的可能性。 三、Rust 实现的计数器合约(基于 Substrate 框架) #!cfg_attr(not(feature = "std"), no_std)

js 复制代码
use codec::{Decode, Encode};
use frame_support::{decl_module, decl_storage, dispatch::Result};
use sp_std::prelude::*;

decl_storage! {
    trait Store for Module<T: Config> as CounterModule {
        Balance: u64;
    }
}

decl_module! {
    pub struct Module<T: Config> for enum Call where origin: T::Origin {
        #[weight = 10_000]
        pub fn deposit(origin, amount: u64) -> Result {
            let who = ensure_signed(origin)?;
            let mut balance = <Balance<T>>::get();
            balance += amount;
            <Balance<T>>::put(balance);
            Ok(())
        }

        #[weight = 10_000]
        pub fn withdraw(origin, amount: u64) -> Result {
            let who = ensure_signed(origin)?;
            let mut balance = <Balance<T>>::get();
            if balance < amount {
                return Err("Insufficient balance");
            }
            balance -= amount;
            <Balance<T>>::put(balance);
            Ok(())
        }

        #[weight = 10_000]
        pub fn init(origin) -> Result {
            let who = ensure_signed(origin)?;
            <Balance<T>>::put(0);
            Ok(())
        }
    }
}

(一)Rust 避免重入攻击的原理 Rust 利用所有权和借用机制以及严格的类型检查来防止重入攻击。在withdraw函数中,先获取当前余额并检查是否足够,然后直接更新余额。Rust 的所有权系统确保在同一时间只有一个所有者可以修改Balance,避免了并发修改导致的重入问题。同时,Rust 的编译时检查可以发现潜在的逻辑错误和类型不匹配问题。 四、Move 语言的优势总结 (一)资源管理的直接性 Move 语言直接将资源作为核心概念,资源的操作规则简单且直接,开发者可以清晰地理解和控制资源的流动和状态变化,相比 Rust 的所有权机制,更专注于区块链领域的资源管理,减少了因复杂所有权转换带来的理解成本。 (二)语法和逻辑的简洁性 Move 的语法设计简洁明了,在处理合约逻辑时,代码结构更加紧凑,对于实现简单的计数器合约等功能,代码量相对较少,可读性更高。而 Rust 基于 Substrate 框架的实现,虽然功能强大,但框架本身的复杂性使得代码相对冗长。 (三)针对区块链场景的优化 Move 语言是专门为区块链智能合约设计的,在处理区块链特定的问题,如账户管理、资源转移等方面,具有天然的优势。相比之下,Rust 虽然可以用于区块链开发,但它是一种通用编程语言,在区块链场景下需要更多的适配和整合。

上述内容从代码实例出发,深入分析了三种语言在应对重入攻击时的表现。如果你有调整语言风格、补充案例等需求,欢迎随时告诉我。

相关推荐
HavenlonLabs14 小时前
重塑链上未来的隐形基石:长期主义下的生态演进
大数据·人工智能·安全·区块链
LedgerNinja20 小时前
2026美国5月未季调CPI年率
区块链
Shota Kishi21 小时前
在 Solana 上实现稳定币基础设施支付:SOL / USDC / EURC 付款与 EURC 结算的工程实践
人工智能·区块链
cmes_love1 天前
股票逐笔level2历史行情下载十档订单薄五档tick分钟下载分享
数据库·区块链
HavenlonLabs2 天前
区块链解决信任分布,AI 需要解决能力控制
人工智能·安全·区块链
选择不变2 天前
死磕牛市主升浪战法(趋势确认 + 洗盘低吸 + 主升浪持有 + 止盈止损)阅读量 1000 万 +,点赞 11 万的文章
区块链
Bczheng12 天前
二十九.签名与脚本(4)--脚本验证例子
区块链
软件工程小施同学2 天前
CCF A区块链论文分享-NDSS 2026(2)-CtPhishCapture:揭露针对加密货币钱包的基于凭证窃取的网络钓鱼诈骗(附pdf)
网络·pdf·区块链
Zhan8611242 天前
数据接口的序列号机制与丢包检测:西班牙行情数据IBEX指数实时行情接入笔记
大数据·数据结构·笔记·区块链
CTA量化套保2 天前
期货量化程序 time.sleep 卡死:天勤单线程与 deadline 替代
python·区块链