8

If _tois left empty, and bytecode is a new contract, should _to.call(bytecode) create a new contract ? Or is it so that when a _to address is included in the transaction then the EVM processes it as a non-contract-creating transaction ?

EDIT: I'm trying to create a new contract via a proposal on the http://ethereum.org/dao framework. This article said that its possible, but it does not work. So my question is, is it possible to create a new contract using .call() ?

enter image description here

  • if _to is empty wouldn't that mean you call a function of an undefined object? This can't work! – Roland Kofler Jun 5 '16 at 14:14
9

Here's an example of how to use the create opcode:

contract Factory {
    function create(bytes code) returns (address addr){
        assembly {
            addr := create(0,add(code,0x20), mload(code))
            jumpi(invalidJumpLabel,iszero(extcodesize(addr)))
        }
    }
}

contract Adder {
    function add(uint a, uint b) returns (uint){
        return a+b;
    }
}

contract Tester {
    Adder a;

    function Tester(address factory){
        a = Adder(Factory(factory).create(
        hex"606060405234610000575b60ad806100186000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063771602f714603c575b6000565b34600057605d60048080359060200190919080359060200190919050506073565b6040518082815260200191505060405180910390f35b600081830190505b929150505600a165627a7a723058205d7bec00c6d410f7ea2a3b03112b597bb3ef544439889ecc1294a77b85eab15e0029"
            ));
        if(address(a) == 0) throw;
    }

    function test(uint x, uint y) constant returns (uint){
        return a.add(x,y);
    }
}

Just deploy the Factory, pass its address into the Tester, and the Tester will create a new Adder, which it will use to add together integers passed to the test function.

The factory will throw if the create failed.

  • Thanks a lot for this example! Can you please explain how did you obtain that bytecode? I tried compiling the Adder contract in Remix but I get slightly different results. – jeff May 1 '17 at 20:35
  • It's just the straight output of compiling Adder. How is your result different? – Tjaden Hess May 1 '17 at 20:44
  • When I add pragma solidity 0.4.8; in the beginning and compile with Remix, this is what I get: 606060405234610000575b60ad806100186000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063771602f714603c575b6000565b34600057605d60048080359060200190919080359060200190919050506073565b6040518082815260200191505060405180910390f35b600081830190505b929150505600a165627a7a72305820e4ea791a28b2087faefce8bb60d7f512153b3d14e381ae6442f5ec19c296c92d0029 – jeff May 1 '17 at 21:02
  • 1
    Why use "add(code,0x20)"? – lixq May 21 '18 at 17:26
  • 1
    The first 32 bytes are the length, so mload(code) is code.length. This says "use the code starting at code+32 with length code.length – Tjaden Hess May 22 '18 at 13:43
4

TL;DR: You can use the inline assembly code create,
(as @Eth pointed out in the comments)

call() is made to expose opcode CALL, not to call the opcode CREATE(s,v,p).

From the documentation:

All three functions call, delegatecall and callcode are very low-level functions and should only be used as a last resort as they break the type-safety of Solidity.

They are low level functions that implement directly the opcodes. CREATE is not one of them.

This can be inferred from the following links:

Here you see create and call opcodes: http://solidity.readthedocs.io/en/latest/control-structures.html?highlight=create

Here you see an explanation of calling a function of an ABI dynamically: http://solidity.readthedocs.io/en/latest/frequently-asked-questions.html#what-does-p-recipient-call-value-p-amount-p-data-do

  • 1
    Looks like OP can use inline assembly create. – eth Jun 13 '16 at 10:51
  • I guess I didnt RTFM accurately @eth – Roland Kofler Jun 13 '16 at 11:16
  • 1
    Your answer is correct that .call() can't be used; I just commented on how OP might be able to do what they are trying to do. – eth Jun 13 '16 at 11:19
1

According to Ethereum Yellow Paper, the OPCODE CALL is used for "message-call into an account". Therefore, essentially, CALL cannot be used directly to deploy a contract.

However, CALL can be used to invoke the public function A of another contract C. If function A further invokes the constructor of C, then this CALL behavior will eventually deploy a new contract, the bytecode of which is exactly the same as C.

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.