9

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

1
  • if _to is empty wouldn't that mean you call a function of an undefined object? This can't work! Jun 5, 2016 at 14:14

3 Answers 3

11

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.

8
  • 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, 2017 at 20:35
  • It's just the straight output of compiling Adder. How is your result different? May 1, 2017 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, 2017 at 21:02
  • 2
    Why use "add(code,0x20)"?
    – lixq
    May 21, 2018 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 May 22, 2018 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

3
  • 1
    Looks like OP can use inline assembly create.
    – eth
    Jun 13, 2016 at 10:51
  • I guess I didnt RTFM accurately @eth Jun 13, 2016 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, 2016 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.