首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当我们真正需要tx.origin时,如何避免使用它?

当我们真正需要tx.origin时,如何避免使用它?
EN

Ethereum用户
提问于 2018-03-19 12:10:50
回答 1查看 793关注 0票数 1

我们应该避免使用推荐来避免使用tx.origin。

然而,有一些情况确实是需要的,比如下面的案例。

假设我们有两个智能契约: Sc1和Sc2,它们都是由同一个所有者创建的。它首先部署了维护令牌平衡的Sc1。然后,所有者创建另一个智能契约Sc2,部署它并允许用户与Sc2交互,并将一些令牌从Sc1转移到Sc2(因此假设一些用户在Sc1中有令牌)。但是只有令牌所有者才能做到这一点

如下所示,我必须使用tx.origin。我知道,如果契约所有者创建了另一个无效的契约,并让用户(令牌所有者)调用它,那么它将能够在token_bsalance中减少他们的Sc1。下面是上述情况的代码(不包括攻击)。

代码语言:javascript
复制
   contract Sc1{
      mapping (address => uint) token_balance;
      mapping (address => bool) valid_caller_contracts;// keeps track 
                                                      //of those contract that can call this contract
      address owner;
      function Sc1(){
        owner = msg.sender;
      }
       // only owner must be able to register. 
      function register_valid_contract() external {
          require(tx.origin==owner);
          valid_caller_contracts[msg.sender] = true;
      }
      function decrement_token(uint val) external{
        require(token_balance[tx.origin] >= val);
        token_balance[tx.origin] -=val;
      }
   }

   contract Sc2{
     mapping (address => uint) token_balance2;
     address owner;
     function SC2(){
        owner = msg.sender;
      }
      function register() external{
       Sc1 c1=Sc1(0x22);//Let's assum the address of Sc1 after it's 
                        //deployed is 0x22
       c1.register_valid_contract();
      }
      // only those who have tokens in Sc1 must be able to tranfer 
      //tokens to Sc2.
      function fetch_tokens(uint val) external{
       Sc1 c1=Sc1(0x22);//Let's assum the address of Sc1 after it's 
                        //deployed is 0x22
      c1.decrement_token(val);
      token_balance2[msg.sender] += val;
      }
    }

问:在上述情况下,我们能避免使用tx.origin吗?

EN

回答 1

Ethereum用户

发布于 2018-03-20 07:35:16

依赖于tx.origin的合同的一个严重问题是,您的合同将不能正确地使用multisig钱包(或任何其他智能合同)。

register_valid_contract问题的解决方案是将契约地址作为参数传递,所有者必须作为额外步骤调用该函数。

代码语言:javascript
复制
function register_valid_contract(address sc2) external {
    require(msg.sender == owner);
    valid_caller_contracts[sc2] = true;
}

另一种方法是SC1使用工厂模式来创建SC2,并在创建时立即注册它们。

对于decrement_token,您可以将msg.sender作为参数传递,但必须确保发送方是有效的约定。

代码语言:javascript
复制
function decrement_token(address from, uint val) external{
    require(valid_caller_contracts[msg.sender]);
    require(token_balance[from] >= val);
    token_balance[from] -=val;
}

在本例中,如果您定义了SC1 y SC2之间的信任关系,例如,如果SC1创建了SC2,那么SC1可以检查发送方地址是SC2,并且信任参数将是正确的。

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

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

复制
相关文章

相似问题

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