首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将DAI从DSR (/ MakerDao)中仅使用合同而不是Dapp前端退出?

如何将DAI从DSR (/ MakerDao)中仅使用合同而不是Dapp前端退出?
EN

Ethereum用户
提问于 2020-02-02 11:51:39
回答 2查看 457关注 0票数 1

我目前正在通过MakerDao (https://oasis.app/save)测试Oasis。在将一些DAI转换成DSR后,用户可以赚取储蓄,只要他们愿意,就可以使用Dapp前端退出按钮提取他们的资金(转换回DAI)。

我喜欢这个想法,但在更多的戴之前,我想知道如何在不使用前端的情况下与合同进行交互。

有人能告诉我如何只使用合同代码来提取所有的储蓄吗?所以不使用绿洲的前端。我想知道我需要调用哪个函数(S),以及作为输入需要填充什么。

下面是部署在储户帐户上的合同代码:

代码语言:javascript
复制
pragma solidity ^0.4.23;

contract DSAuthority {
    function canCall(
        address src, address dst, bytes4 sig
    ) public view returns (bool);
}

contract DSAuthEvents {
    event LogSetAuthority (address indexed authority);
    event LogSetOwner     (address indexed owner);
}

contract DSAuth is DSAuthEvents {
    DSAuthority  public  authority;
    address      public  owner;

    constructor() public {
        owner = msg.sender;
        emit LogSetOwner(msg.sender);
    }

    function setOwner(address owner_)
        public
        auth
    {
        owner = owner_;
        emit LogSetOwner(owner);
    }

    function setAuthority(DSAuthority authority_)
        public
        auth
    {
        authority = authority_;
        emit LogSetAuthority(authority);
    }

    modifier auth {
        require(isAuthorized(msg.sender, msg.sig));
        _;
    }

    function isAuthorized(address src, bytes4 sig) internal view returns (bool) {
        if (src == address(this)) {
            return true;
        } else if (src == owner) {
            return true;
        } else if (authority == DSAuthority(0)) {
            return false;
        } else {
            return authority.canCall(src, this, sig);
        }
    }
}

contract DSNote {
    event LogNote(
        bytes4   indexed  sig,
        address  indexed  guy,
        bytes32  indexed  foo,
        bytes32  indexed  bar,
        uint              wad,
        bytes             fax
    ) anonymous;

    modifier note {
        bytes32 foo;
        bytes32 bar;

        assembly {
            foo := calldataload(4)
            bar := calldataload(36)
        }

        emit LogNote(msg.sig, msg.sender, foo, bar, msg.value, msg.data);

        _;
    }
}

// DSProxy
// Allows code execution using a persistant identity This can be very
// useful to execute a sequence of atomic actions. Since the owner of
// the proxy can be changed, this allows for dynamic ownership models
// i.e. a multisig
contract DSProxy is DSAuth, DSNote {
    DSProxyCache public cache;  // global cache for contracts

    constructor(address _cacheAddr) public {
        require(setCache(_cacheAddr));
    }

    function() public payable {
    }

    // use the proxy to execute calldata _data on contract _code
    function execute(bytes _code, bytes _data)
        public
        payable
        returns (address target, bytes32 response)
    {
        target = cache.read(_code);
        if (target == 0x0) {
            // deploy contract & store its address in cache
            target = cache.write(_code);
        }

        response = execute(target, _data);
    }

    function execute(address _target, bytes _data)
        public
        auth
        note
        payable
        returns (bytes32 response)
    {
        require(_target != 0x0);

        // call contract in current context
        assembly {
            let succeeded := delegatecall(sub(gas, 5000), _target, add(_data, 0x20), mload(_data), 0, 32)
            response := mload(0)      // load delegatecall output
            switch iszero(succeeded)
            case 1 {
                // throw if delegatecall failed
                revert(0, 0)
            }
        }
    }

    //set new cache
    function setCache(address _cacheAddr)
        public
        auth
        note
        returns (bool)
    {
        require(_cacheAddr != 0x0);        // invalid cache address
        cache = DSProxyCache(_cacheAddr);  // overwrite cache
        return true;
    }
}

// DSProxyFactory
// This factory deploys new proxy instances through build()
// Deployed proxy addresses are logged
contract DSProxyFactory {
    event Created(address indexed sender, address indexed owner, address proxy, address cache);
    mapping(address=>bool) public isProxy;
    DSProxyCache public cache = new DSProxyCache();

    // deploys a new proxy instance
    // sets owner of proxy to caller
    function build() public returns (DSProxy proxy) {
        proxy = build(msg.sender);
    }

    // deploys a new proxy instance
    // sets custom owner of proxy
    function build(address owner) public returns (DSProxy proxy) {
        proxy = new DSProxy(cache);
        emit Created(msg.sender, owner, address(proxy), address(cache));
        proxy.setOwner(owner);
        isProxy[proxy] = true;
    }
}

// DSProxyCache
// This global cache stores addresses of contracts previously deployed
// by a proxy. This saves gas from repeat deployment of the same
// contracts and eliminates blockchain bloat.

// By default, all proxies deployed from the same factory store
// contracts in the same cache. The cache a proxy instance uses can be
// changed.  The cache uses the sha3 hash of a contract's bytecode to
// lookup the address
contract DSProxyCache {
    mapping(bytes32 => address) cache;

    function read(bytes _code) public view returns (address) {
        bytes32 hash = keccak256(_code);
        return cache[hash];
    }

    function write(bytes _code) public returns (address target) {
        assembly {
            target := create(0, add(_code, 0x20), mload(_code))
            switch iszero(extcodesize(target))
            case 1 {
                // throw if contract failed to deploy
                revert(0, 0)
            }
        }
        bytes32 hash = keccak256(_code);
        cache[hash] = target;
    }
}

来源:https://etherscan.io/address/0xad01c274961a55a493991e1f63e0c362aabf6705#code

当单击Dapp上的退出按钮时,似乎调用了execute()函数,但我不知道什么是bytes _data。Metamask为这个参数显示了一个很长的输入(228个字节),但我不知道它意味着什么,如果需要的话,人们如何自己猜测它。有人知道准确地调用什么以及作为输入应该填写什么吗?

作为一个分散的应用程序,如果由于任何原因前端不可用(维护、更新.),这将非常有用。一个人想要回他的钱。

谢谢您:)

EN

回答 2

Ethereum用户

发布于 2020-02-02 12:09:26

但我不明白什么是bytes _data

它是一个编码的函数调用,它在函数execute中执行(通过程序集)。

下面是一个编码函数调用的示例:

代码语言:javascript
复制
bytes4 selector = bytes4(uint256(keccak256("someFunc(address,uint256,bool)") >> 224));
bytes memory data = abi.encodeWithSelector(selector, someAddress, someUint256, someBool);

当然,上面的编码是在链上(在合同中)执行的,而您需要计算离链(例如,web3.js脚本)中的相同内容,然后将其传递给合同的函数。

票数 0
EN

Ethereum用户

发布于 2020-02-11 23:40:22

万一绿洲网站消失了怎么办?因为我的硬币被委托给一份困难的合同,我的硬币是否处于危险之中?

这就是为什么我也想知道如何才能只使用合同代码来提取我的储蓄。

从上面的答案看,似乎很复杂,我不知道如何生成该数据字段。也许有人可以一步一步地描述水电部合同的相互作用,以退出绿洲DSR合同?

票数 0
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/79529

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档