Skip to content

Instantly share code, notes, and snippets.

@eternauta1337
Created April 4, 2019 01:35
Show Gist options
  • Save eternauta1337/af5960a0ef871de7f8f794b821e47818 to your computer and use it in GitHub Desktop.
Save eternauta1337/af5960a0ef871de7f8f794b821e47818 to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.5.1+commit.c8a2cb62.js&optimize=false&gist=
pragma solidity ^0.5.7;
import "./ImplementationProvider.sol";
contract Changeling {
constructor(address implementationProvider) public {
// Request the current implementation address from the provider.
address implementation = ImplementationProvider(implementationProvider).getImplementation();
// Retrieve the runtime code at the target address.
bytes memory targetCode = getCodeAt(implementation);
// Override Solidity's constructor logic and return the
// retrieved runtime code instead.
assembly {
let size := extcodesize(implementation)
return(0xc0, size)
}
}
function getCodeAt(address _addr) private view returns (bytes memory o_code) {
assembly {
// retrieve the size of the code, this needs assembly
let size := extcodesize(_addr)
// allocate output byte array - this could also be done without assembly
// by using o_code = new bytes(size)
o_code := mload(0x40)
// new "memory end" including padding
mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f))))
// store length in memory
mstore(o_code, size)
// actually retrieve the code, this needs assembly
extcodecopy(_addr, add(o_code, 0x20), 0, size)
}
}
}
function computeAddress(creatorAddress, saltHex, byteCode) {
return `0x${web3.utils.sha3(`0x${[
'ff',
creatorAddress,
saltHex,
web3.utils.sha3(byteCode)
].map(x => x.replace(/0x/, ''))
.join('')}`).slice(-40)}`.toLowerCase();
}
computeAddress(
"0xf383fd112e927278aeff780415eb273ce652d5d9",
"0x7B",
"0x6080604052348015600f57600080fd5b50604051602080608283398101806040526020811015602d57600080fd5b81019080805190602001909291905050506060604d82605660201b60201c565b9050813b8060c0f35b6060813b6040519150601f19601f602083010116820160405280825280600060208401853c5091905056fe000000000000000000000000af27dcbd65de737ab7e492dc8dd0faf3aca78604"
);
pragma solidity ^0.5.7;
contract CreateFactory {
event InstanceDeployed(address addr);
function createInstance_1(bytes memory code) public {
address addr;
assembly {
// Create the new contract.
addr := create(
0, // value (wei)
add(code, 0x20), // code start position
mload(code) // code length
)
// Check if resulting address has code in it.
if iszero(extcodesize(addr)) {
revert(0, 0)
}
}
emit InstanceDeployed(addr);
}
function createInstance_2(bytes memory code, uint256 salt) public {
address addr;
assembly {
// Create the new contract.
addr := create2(
0, // value (wei)
add(code, 0x20), // code start position
mload(code), // code length
salt // salt
)
// Check if resulting address has code in it.
if iszero(extcodesize(addr)) {
revert(0, 0)
}
}
emit InstanceDeployed(addr);
}
}
pragma solidity ^0.5.7;
contract ImplementationProvider {
address private implementation;
function setImplementation(address _implementation) public {
implementation = _implementation;
}
function getImplementation() public view returns (address) {
return implementation;
}
}
pragma solidity ^0.5.7;
contract Sample {
string value;
function setValue(string memory _value) public {
value = _value;
}
function die() public {
selfdestruct(msg.sender);
}
}
pragma solidity ^0.5.7;
contract SampleUpgraded {
string value;
uint256 anotherValue;
function setValue(string memory _value) public {
value = _value;
}
function setAnotherValue(uint256 _anotherValue) public {
anotherValue = _anotherValue;
}
function die() public {
selfdestruct(msg.sender);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment