一个蜜罐合约的解析（二）调用隐藏
Tags: solidity, honeypot, ethscan
Published: 2022-02-28 04:46:26

## 前文

上次发了，[一个蜜罐合约的解析 | 登链社区 | 深入浅出区块链技术 (learnblockchain.cn)](https://learnblockchain.cn/article/3509) 看的人很多，评论也不少，是我发的文章中评论最多的文章。

在写的过程中，我也是边写边试，边分析，前面的部分给部分看文章的人一些误导，深表歉意，在写的过程中，我也学习了不少。
我把上次那个过程再讲一次，并且把各个调用的链接在ethscan上的都发出来，后面再把调用New的合约代码复原一下。

## 流程

1，部署合约， [Ethereum Transaction Hash (Txhash) Details | Etherscan](https://etherscan.io/tx/0x691A0B51049B0A53B2E6AC8AE3D6D0B5EC8D90AF69092E022AAB809DC2BC8262)
2，调用New设置答案hash [Ethereum Transaction Hash (Txhash) Details | Etherscan](https://etherscan.io/tx/0x8874F555001B19A735CDB5224F67DF3EC83DB5F25782D5BEC698C433D270133B)
3，开始Start，投入2个eth [Ethereum Transaction Hash (Txhash) Details | Etherscan](https://etherscan.io/tx/0x741C21A737D485FE23F03116C5B8E49A44FC896D473520B32AC994D3283C61F5)
4，有人Try，投入至少1个eth [Ethereum Transaction Hash (Txhash) Details | Etherscan](https://etherscan.io/tx/0x9765B44C3E3ACF2A9609E89C41D8D67FD926DE8EB43B8D41F0948A2D9147CD73)
5，Stop 收入，转回自己的钱包。[Ethereum Transaction Hash (Txhash) Details | Etherscan](https://etherscan.io/tx/0xD270AC214EDAA775D68BAD267C678D782DDCE58A44835B2B2625ECF19C4F1AE1)

合约的调用历史列表：

[Contract d732e40d353aa772a7f82b4b310e75925853a040 in Ethereum - Ethereum Contract Library by Dedaub (contract-library.com)](https://contract-library.com/contracts/Ethereum/d732e40d353aa772a7f82b4b310e75925853a040/transactions)

## 小结

现在看来，其实这个合约没有什么技术含量，有两个可取之处：
1，部署合约时候设置管理员
2，在ethscan上隐藏了`New`调用。

## 合约调用隐藏

下面谈谈调用New调用的合约：
看上面的New调用记录可以知道，他是通过合约调用合约来隐藏这个调用的，而发起调用这个合约是没有审计的，所以你并不能在ethscan上看到发起New调用的函数名。
调用时候的input  [Ethereum Transaction Hash (Txhash) Details | Etherscan](https://etherscan.io/tx/0x8874F555001B19A735CDB5224F67DF3EC83DB5F25782D5BEC698C433D270133B)
![16445505331.png](https://img.learnblockchain.cn/attachments/2022/02/0NtYxuUc6205d992ec567.png)

合约代码：
[Contract 0x1ba21C6cfcD3D082d8Bbe95bC5B78F4eDC3e80D4 in Ethereum - Ethereum Contract Library by Dedaub (contract-library.com)](https://contract-library.com/contracts/Ethereum/0x1ba21C6cfcD3D082d8Bbe95bC5B78F4eDC3e80D4)

```
// Decompiled at www.contract-library.com
// 2022.01.21 17:07 UTC
// Data structures and variables inferred from the use of storage instructions
address owner; //STORAGE[0x0] bytes 0 to 19
function fallback() public payable {        
    find similar
}
function 0x2000df44(address varg0, uint256 varg1, uint256 varg2) public payable {
    find similar
    require(msg.data.length - 4 >= 96);
    require(varg0 == varg0);
    require(varg1 <= 0xffffffffffffffff);
    require(4 + varg1 + 31 < msg.data.length);
    require((?).length <= 0xffffffffffffffff);
    require(4 + varg1 + (?).length + 32 <= msg.data.length);
    require(msg.sender == owner);
    v0 = new array[]((?).length);
    MEM[4 + MEM[64] + (?).length + 96] = 0;
    require(varg0.code.size);
    v1 = varg0.New(v0, varg2).gas(msg.gas);
    require(v1);
    // checks call status, propagates error data on error
}
// Note: The function selector is not present in the original solidity code.
// However, we display it for the sake of completeness.
function __function_selector__(uint256 function_selector) public payable {
    MEM[64] = 128;
    require(!msg.value);
    if(msg.data.length >= 4) {
        if(0x2000df44 == function_selector >> 224) {
            0x2000df44();
        }
    }
    fallback();
}
```

翻译成solidity代码如下：

```
contract Hacker {
    address owner;

    constructor() {
        owner = msg.sender;
    }

    function myCall(
        address varg0,
        uint256 varg1,
        uint256 varg2
    ) public payable {
        require(owner == msg.sender);
        defi_game(varg0).New(varg1, varg2);
    }
}
```

所以就这么简单，就这样调用ethscan上就没有这个合约的这一条的调用记录。
ethscan上没有，其他地方还是有的。

## 一点猜想

我估计把`multicall`改改应该能够做到更好的隐藏。

```
function multicall(bytes[] calldata data) public payable override returns (bytes[] memory results) {
        results = new bytes[](data.length);
        for (uint256 i = 0; i < data.length; i++) {
            (bool success, bytes memory result) = address(this).delegatecall(data[i]);

            if (!success) {
                // Next 5 lines from https://ethereum.stackexchange.com/a/83577
                if (result.length < 68) revert();
                assembly {
                    result := add(result, 0x04)
                }
                revert(abi.decode(result, (string)));
            }

            results[i] = result;
        }
    }
```

怎么改呢，就改个函数名就够了。
大家别干坏事，我也只是技术交流。