想请教一个 solidity 以太坊合约的代码问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
whoami9894
V2EX    Solidity

想请教一个 solidity 以太坊合约的代码问题

  •  1
     
  •   whoami9894 2018-12-15 23:37:19 +08:00 5004 次点击
    这是一个创建于 2545 天前的主题,其中的信息可能已经有所发展或是发生改变。
    pragma solidity ^0.4.23; contract Preservation { // public library contracts address public timeZone1Library; address public timeZone2Library; address public owner; uint storedTime; // Sets the function signature for delegatecall bytes4 constant setTimeSignature = bytes4(keccak256("setTime(uint256)")); event FLAG(string b64email, string slogan); constructor(address _timeZone1LibraryAddress, address _timeZone2LibraryAddress) public { timeZone1Library = _timeZone1LibraryAddress; timeZone2Library = _timeZone2LibraryAddress; owner = msg.sender; } // set the time for timezone 1 function setFirstTime(uint _timeStamp) public { timeZone1Library.delegatecall(setTimeSignature, _timeStamp); } // set the time for timezone 2 function setSecondTime(uint _timeStamp) public { timeZone2Library.delegatecall(setTimeSignature, _timeStamp); } function CaptureTheFlag(string b64email) public{ require (owner == msg.sender); emit FLAG(b64email, "Congratulations to capture the flag!"); } } // Simple library contract to set the time contract LibraryContract { // stores a timestamp uint storedTime; function setTime(uint _time) public { storedTime = _time; } } 

    对以太坊相关一窍不通,看了不少文章还是有点摸不着头脑....

    这是区块链安全想关的,想请教一下这段合约代码放在 Remix 上编译运行后调用CaptureTheFlag函数前有什么约束吗(这里的目的是调用该函数),我的猜想这里时间戳可能与uint256溢出有关

    第 1 条附言    2018-12-16 00:14:00 +08:00

    大概两个合约相当于两个类?,那么

    • setTime函数在这里是干嘛的

    • 在Remix IDE里调用函数的结果是测试性的?(未写入区块或未连接合约地址?)

    15 条回复    2018-12-16 12:18:08 +08:00
    liangdu
        1
    liangdu  
       2018-12-16 01:38:53 +08:00 via Android
    capturetheflag 的约束在 request 写着了,合约的发起者必须是 owner,owner 通常在初始化的时候设置,你的代码不全,看不出完整业务场景。就你给出的代码来讲,settime 就是给 preservation 合约实例的 librarycontract 成员设置属性值而已,settime 可以破例看做成员方法(ps:智能合约的设计思想不能和面向对象一概而论)
    liangdu
        2
    liangdu  
       2018-12-16 01:46:18 +08:00 via Android   2
    这贴好冷门,答漏了

    remix 是通过跟本地的测试节点进程交互(js 调用 rpc 接口通讯),实现高仿真测试。实际上可以理解为就是生产了,只是没有和公链一个网络。

    但是测试结果准确性不能证明在它的派生链也有效,比如基于 eth 拓展的 quorum 框架,虽然都是 eth 虚拟机,但是有些兼容问题。
    zsszuh
        3
    zsszuh  
       2018-12-16 01:49:02 +08:00 via Android   1
    谁知道以太币怎么造的?
    whoami9894
        4
    whoami9894  
    OP
       2018-12-16 08:47:52 +08:00 via Android
    @liangdu

    感谢回复,确实冷门←_←,原来都没听说过 solidity。还想请问一下:

    capturetheflag 的 owner 是理解为合约的创造者==消息的发送者吗。这里需要以自己的邮箱为参数调用 capturetheflag 来获得 flag,但我调用了好像没有什么用,remix 里也没有报错信息(可能是我没看到)

    这个合约无法查看 abi(和我看别人的项目不太一样),且合约地址的 code 里有类似汇编的代码,那个是可以反编译生成完整代码的吗。题目给了一个 sol 文件就是我贴上的,还有一个合约地址,如果按您说的代码不全可能需要从操作码反编译?(或者合约没有开源)
    Hconk
        5
    Hconk  
       2018-12-16 10:00:08 +08:00 via Android   1
    根据代码,owner 是你在创建合约时的发送人,有些合约提供了修改 owner 的功能,这样的合约 owner 就不一定是合约的发布者了。msg.sender 是你调用这个合约时使用的地址。

    timeZone1Library 和 timeZone2Library 是另外两个合约的地址,settime 具体什么功能是业务相关的,要看另外两个合约怎么写,这里应该可以理解为 c++里面的前置声明,用于在这个合约上的调用外部的函数。
    whoami9894
        6
    whoami9894  
    OP
       2018-12-16 10:18:16 +08:00
    @Hconk

    感谢回复

    是不是在构造函数里修改了 own 地址为 msg.sender,这里的 time1 和 time2 是两个合约地址,我可以填入自己的合约代码然后 delegatecall 调用是吗(不知道理解的对不对)

    还有就是我调用 capturetheflag 不知道为什么没有写入`ropsten.etherscan.io/0x_______`的 event 中
    Hconk
        7
    Hconk  
       2018-12-16 10:35:34 +08:00 via Android
    @whoami9894 构造函数肯定只在发布合约时会调用一次,调用时的 msg.sender 就是合约创建者。

    两个合约地址也是初始化时候填写的地址,是通过 delegatecall 去调用这两个合约的 settime 方法。

    remix 编译器需要选择使用哪个网络,有本地浏览器上的 vm,还有 mainnet,或者自定义,不知道你有没有选对。你先查看你那个地址的有没有交易记录,再看交易的详情 data 数据有没有问题。
    liangdu
        8
    liangdu  
       2018-12-16 10:57:54 +08:00 via Android
    我通常用 nodejs 配合 truffle test 来测试智能合约,通过 web3 接口可以监听到合约的事件(事务被打包时抛出)。remix 没怎么用,因为当时需要做测试驱动开发,用 remix 不适合。你也可以不监听,truffle 在 test 报错的时候会列出所有合约抛出的 event

    在代码最后加上 assert(false)就可以人为制造错误了
    whoami9894
        9
    whoami9894  
    OP
       2018-12-16 11:25:13 +08:00
    @Hconk
    @liangdu

    我 Google 出了这道题的解法:是 delegatecall 函数的漏洞来恶意修改 owner,可是我在按题解测试的时候依旧死在`require (owner == msg.sender);`

    http://www.bendawang.site/2018/11/13/Zeppelin-ethernaut-writeup/#Preservation-X

    https://blog.riskivy.com/智能合约 ctf:ethernaut-writeup-part-4/
    whoami9894
        10
    whoami9894  
    OP
       2018-12-16 11:48:42 +08:00
    @Hconk
    @liangdu

    ![]( https://upload-images.jianshu.io/upload_images/11356161-30b8aba42e7fabda.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

    ![]( https://upload-images.jianshu.io/upload_images/11356161-78ad090a02535efa.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

    我已经把 owner 地址修改为我 account 地址了,可是 debug 依旧在`require (owner == msg.sender);`那里报错
    liangdu
        11
    liangdu  
       2018-12-16 11:56:25 +08:00 via Android
    哈啊哈,不对,account 不是你理解的邮箱地址,而且钱包地址。也就外部地址。


    你可以提供更多你的资料,比如报错信息,放在 v2ex。
    imgode
        12
    imgode  
       2018-12-16 12:05:11 +08:00 via Android
    owner 是这个合约的部署者,msg.sender 是这个方法的调用者,require 是相当于一个判断,合约的部署者和调用者一致才往下执行,否则抛出异常,一般会写一个 modifier 来修饰这个函数而不是用 require 这样
    imgode
        13
    imgode  
       2018-12-16 12:08:50 +08:00 via Android
    部署合约的时候会调用 constructor 构造函数,构造函数里写了 owner=msg.sender 所以你这个合约的拥有者也就是 owner 就是你部署合约的那个账户,在调用下面的方法的时候,同样用你部署合约那个账户调用即可,setTime 就是给一个状态变量赋值
    whoami9894
        14
    whoami9894  
    OP
       2018-12-16 12:14:07 +08:00
    @imgode

    可是我的函数依旧卡在 require 的判断

    可能我理解有误,我在 remix 里构建实例并且获得了一个地址是部署吗
    whoami9894
        15
    whoami9894  
    OP
       2018-12-16 12:18:08 +08:00
    @liangdu

    绕晕了,我的 account 地址是 remix 右上角的 0xca35b7d915458ef540ade6068dfe2f44e8fa733c 那个吗。

    好像没有友好的报错信息,我是在 remix 的 debugger 里看到 require 那一行标红了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     965 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 22:35 PVG 06:35 LAX 14:35 JFK 17:35
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86