我们应该避免使用推荐来避免使用tx.origin。
然而,有一些情况确实是需要的,比如下面的案例。
假设我们有两个智能契约: Sc1和Sc2,它们都是由同一个所有者创建的。它首先部署了维护令牌平衡的Sc1。然后,所有者创建另一个智能契约Sc2,部署它并允许用户与Sc2交互,并将一些令牌从Sc1转移到Sc2(因此假设一些用户在Sc1中有令牌)。但是只有令牌所有者才能做到这一点
如下所示,我必须使用tx.origin。我知道,如果契约所有者创建了另一个无效的契约,并让用户(令牌所有者)调用它,那么它将能够在token_bsalance中减少他们的Sc1。下面是上述情况的代码(不包括攻击)。
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吗?
发布于 2018-03-20 07:35:16
依赖于tx.origin的合同的一个严重问题是,您的合同将不能正确地使用multisig钱包(或任何其他智能合同)。
register_valid_contract问题的解决方案是将契约地址作为参数传递,所有者必须作为额外步骤调用该函数。
function register_valid_contract(address sc2) external {
require(msg.sender == owner);
valid_caller_contracts[sc2] = true;
}另一种方法是SC1使用工厂模式来创建SC2,并在创建时立即注册它们。
对于decrement_token,您可以将msg.sender作为参数传递,但必须确保发送方是有效的约定。
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,并且信任参数将是正确的。
https://ethereum.stackexchange.com/questions/43195
复制相似问题