Skip to content

Workshop #20 Contracts To Check msg.sender

BokkyPooBah edited this page Dec 7, 2017 · 3 revisions

Exercise to go with Meetup #20 [Advance] Smart Contract Design And Developing Ethereum (In)App Wallets

pragma solidity ^0.4.18;

// ----------------------------------------------------------------------------
// Sample contract to check the account represented by msg.sender and
// tx.origin
//
// Deployment:
// 1. Use remix.ethereum.org to compile SubContract
//   a. Select SubContract in the Compile tab
//   b. Click on Details
//   c. Copy BYTECODE into your clipboard
// 2. Get some Ropsten Testnet ethers if you don't already have some - see
//   https://www.reddit.com/r/ethdev/comments/72ltwj/the_new_if_you_need_some_ropsten_testnet_ethers/
// 3. Deploy SubContract to the Ropsten network using MyEtherWallet
//   a. Select the Ropsten network from the top right
//   b. Select the Contracts tab
//   c. Click on Deploy Contracts
//   d. Paste in the BYTECODE from 1. above
//   e. Unlock your account and send your transaction
//   f. Search for your new contract by entering your account into
//     https://ropsten.etherscan.io/
//   g. Verify your contract in EtherScan
// 4. Deploy and verify MainContract using steps 1., 2. and 3. above
// 5. Call MainContract.setSubContract(...) providing the address of your
//    deployed SubContract
// 6. Send a 0 or non-0 transaction to your MainContract address and
//   note down the addresses in the logged event in your MainContract and
//   SubContract address
//
// Enjoy. (c) BokkyPooBah / Bok Consulting Pty Ltd 2017. The MIT Licence.
// ----------------------------------------------------------------------------

// ----------------------------------------------------------------------------
// Owned contract
// ----------------------------------------------------------------------------
contract Owned {
    address public owner;
    address public newOwner;

    event OwnershipTransferred(address indexed _from, address indexed _to);

    modifier onlyOwner {
        require(msg.sender == owner);
        _;
    }

    function Owned() public {
        owner = msg.sender;
    }
    function transferOwnership(address _newOwner) public onlyOwner {
        newOwner = _newOwner;
    }
    function acceptOwnership() public {
        require(msg.sender == newOwner);
        OwnershipTransferred(owner, newOwner);
        owner = newOwner;
        newOwner = address(0);
    }
}


contract MainContract is Owned {
    SubContract public subContract;
    
    event SubContractUpdated(address indexed oldSubContract, address indexed newSubContract);
    event LogMainContractInfo(address indexed msgSender, address indexed txOrigin, uint msgValue);
    
    function setSubContract(address _subContract) public {
        SubContractUpdated(subContract, _subContract);
        subContract = SubContract(_subContract);
    }
    
    function () public payable {
        require(subContract != address(0));
        LogMainContractInfo(msg.sender, tx.origin, msg.value);
        subContract.transfer(msg.value);
    }
}


contract SubContract is Owned {
    event LogSubContractInfo(address indexed msgSender, address indexed txOrigin, uint msgValue);

    function () public payable {
        LogSubContractInfo(msg.sender, tx.origin, msg.value);
    }
}