You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Solidity合约rent函数无法实现Leaser向Owner转ETH的问题排查

问题定位与修复方案

核心转账失败原因

  • 未校验交易附带的ETH金额
    getRent函数声明为payable,但仅通过msg.sender.balance > _leaserAmount校验租户账户余额,未检查本次交易实际发送的ETH(msg.value)是否等于租金_leaserAmount。若租户未在调用时附带对应ETH,合约余额不足,执行_owner.transfer(_leaserAmount)会直接失败。
  • checkRentAmount函数调用参数错误
    在getRent中调用checkRentAmount(_owner,property.MonthPrice)时,第二个参数误传为房产价格,而该函数要求传入房产在PropertyMap中的索引。这会导致函数读取错误的房产数据,大概率触发"Invalid Price"回滚;若测试场景中刚好价格等于索引,会隐藏逻辑异常。
  • 转账方式的局限性
    使用transfer会强制限制2300 gas,若房主是合约地址且其receive/fallback函数消耗gas超过该值,转账会失败。

修复后的关键代码片段

修正getRent函数

function getRent (
   address payable _leaser,
   address payable _owner,
   uint256 _HouseShopNumber,
   string memory _ProportName,
   uint256 _RentEnd,
   uint256 _leaserAmount) 
   external payable {
     require(!locked, "Reentrant call detected!");
     require(_owner != _leaser,"you cant rent yourself");
     require(msg.sender == _leaser,"you are not leaser");
     require(!checkRent(_owner,_HouseShopNumber),"already rented");
     Property storage property = PropertyMap[_owner][_HouseShopNumber];
     // 修正参数:传入房产索引而非价格
     require(checkRentAmount(_owner, _HouseShopNumber) == _leaserAmount,"Invalid Price" );  
     // 校验本次交易发送的ETH与租金匹配
     require(msg.value == _leaserAmount,"Sent ETH does not match rent amount");    
           
    
      contracts memory _contracts;
      _contracts.leaser = _leaser;
      _contracts.owner = _owner;
      _contracts.ProportName =_ProportName;
      _contracts.RentStart = block.timestamp;
      _contracts.RentEnd = _RentEnd + block.timestamp;
      _contracts.RentPrice = _leaserAmount;
      contractsMap[_owner].push(_contracts);

     locked = true;   

      // 使用call替代transfer,处理返回值确保转账成功
      (bool success,) = _owner.call{value: _leaserAmount}("");
      require(success, "Transfer to owner failed");

     locked = false;   
    
      property.active = true;

      emit getRent1(_leaser, _HouseShopNumber, _ProportName, _RentEnd);
}

修正setHouseShop中的空语句

将无意义的property.active;改为显式赋值(bool默认值虽为false,显式赋值更清晰):

Property memory property;
property.owner = _owner;
property.AssetName = _AssetName;
property.MonthPrice = _amount;
property.active = false; // 修正空语句

额外注意事项

  • 调用getRent时,必须在交易中附带与_leaserAmount相等的ETH,否则会触发"Sent ETH does not match rent amount"回滚。
  • 若房主为合约地址,需确保其receive或fallback函数的gas消耗在区块gas限制范围内。

内容的提问来源于stack exchange,提问作者Mentalist

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 10:37:13