0

Simple question, but I couldn’t figure the answer.

Are there plans/EIP to use the second parameter of DELEGATECALL ? Or am I wrong (in which case the parameter isn’t ignored) ?

In c++ Ethereum evm lies this code :

if (m_ext->balance(m_ext->myAddress) >= callParams->valueTransfer && m_ext->depth < 1024)
{
    callParams->onOp = m_onOp;
    callParams->senderAddress = m_OP == Instruction::DELEGATECALL ? m_ext->caller : m_ext->myAddress; // if Delegatecall the sender address and value stays the same
    // STATICCALL is rejected by !m_schedule->haveStaticCall elsewhere
    callParams->receiveAddress = (m_OP == Instruction::CALL || m_OP == Instruction::STATICCALL) ? callParams->codeAddress : m_ext->myAddress; // if opcode isn’t CALL, the target address to call is the current one.
    callParams->data = bytesConstRef(m_mem.data() + inOff, inSize);
    o_output = bytesRef(m_mem.data() + outOff, outSize);
    return true;
}
return false;

and in Go Ethereum at execution.go :

func execDelegateCall(env vm.Environment, caller vm.ContractRef, originAddr, toAddr, codeAddr *common.Address, codeHash common.Hash, input, code []byte, gas, gasPrice, value *big.Int) (ret []byte, addr common.Address, err error)    {
    evm := env.Vm()
    // Depth check execution. Fail if we're trying to execute above the
    // limit.
    if env.Depth() > callCreateDepthMax {
        caller.ReturnGas(gas, gasPrice)
        return nil, common.Address{}, errCallCreateDepth
    }

    snapshot := env.SnapshotDatabase()

    var to vm.Account
    if !env.Db().Exist(*toAddr) {
        to = env.Db().CreateAccount(*toAddr)
    } else {
        to = env.Db().GetAccount(*toAddr)
    }

    // Iinitialise a new contract and make initialise the delegate values
    contract := vm.NewContract(caller, to, value, gas, gasPrice).AsDelegate()
    contract.SetCallCode(codeAddr, codeHash, code)
    defer contract.Finalise()

    ret, err = evm.Run(contract, input)
    if err != nil {
        contract.UseGas(contract.Gas)

        env.RevertToSnapshot(snapshot)
    }

    return ret, addr, err
}

where .AsDelegate() returns the caller address of the address which is to be DELEGATECALLED (and this is that address which is called at evm.Run) :

// AsDelegate sets the contract to be a delegate call and returns the current
// contract (for chaining calls)
    func (c *Contract) AsDelegate() *Contract {
    c.DelegateCall = true
    // NOTE: caller must, at all times be a contract. It should never happen
    // that caller is something other than a Contract.
    c.CallerAddress = c.caller.(*Contract).CallerAddress
    return c
}

So while the target parameter is read from the stack, it is ignored at a later stage as shown in those references implementations.

1

The second parameter of DELEGATECALL is to, which is very much used. I assume what you're referring to is the line in the yellow paper that reads "Compared with CALL, DELEGATECALL takes one fewer arguments. The omitted argument is µs[2]." This is just saying that DELEGATECALL is the same as CALL except it doesn't have the parameter at index 2 that CALL does (which is actually the 3rd argument). The parameter that is omitted from DELEGATECALL is value, e.g. you can't send eth during a delegatecall.

  • I knew what was the omitted parameter. But, since DELEGATECALL can only be used to call current address but differently,to is ignored, right ? – user2284570 Jun 18 '18 at 20:35
  • 1
    No. to denotes the address whose code you want to call within the current contracts context. to is very much used. – flygoing Jun 18 '18 at 20:37
  • Sorry I don’t understand, do you mean a contract can be stored at several addresses, or that DELEGATECALL can be used to call a different contract stored at a different address ? Because of course, I know an address can store several contracts. – user2284570 Jun 18 '18 at 20:39
  • Or do you mean if the address is different, value and msg.sender aren’t preserved ? – user2284570 Jun 19 '18 at 12:57
  • 1. DELEGATECALL is for calling contracts at other addresses. I don't see why anyone would DELEGATECALL into itself. 2. An address can't store multiple contracts. 3. value and msg.sender are always preserved for DELEGATECALL, no matter what. – flygoing Jun 19 '18 at 18:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.