コード例 #1
0
class ClearAdminTest(ConfluxTestFramework):
    def set_test_params(self):
        self.num_nodes = 8

    def setup_network(self):
        self.setup_nodes()
        connect_sample_nodes(self.nodes, self.log)
        sync_blocks(self.nodes)
        self.rpc = RpcClient(self.nodes[0])

    def run_test(self):
        start_p2p_connection(self.nodes)
        block_gen_thread = BlockGenThread(self.nodes, self.log)
        block_gen_thread.start()

        gas_price = 1
        gas = CONTRACT_DEFAULT_GAS
        genesis_key = default_config["GENESIS_PRI_KEY"]
        genesis_addr = encode_hex_0x(priv_to_addr(genesis_key))
        nonce = 0
        test_account_key = default_config["GENESIS_PRI_KEY_2"]
        test_account_addr = encode_hex_0x(priv_to_addr(test_account_key))
        null_addr = "0x0000000000000000000000000000000000000000"

        file_dir = os.path.dirname(os.path.realpath(__file__))
        control_contract_file_path = os.path.join(file_dir, "..",
                                                  "internal_contract",
                                                  "metadata",
                                                  "AdminControl.json")
        control_contract_dict = json.loads(
            open(control_contract_file_path, "r").read())
        admin_control_contract = get_contract_instance(
            contract_dict=control_contract_dict)
        admin_control_contract_addr = "0x0888000000000000000000000000000000000000"

        # Deploy a new instance of the create2factory other than the genesis block,
        # so that the admin is the genesis_addr, in order to test hijackAdmin function
        # in clear_admin_test_contract_addr.sol.
        self.tx_conf = {
            "from": Web3.toChecksumAddress(genesis_addr),
            "nonce": int_to_hex(nonce),
            "gas": int_to_hex(gas),
            "gasPrice": int_to_hex(gas_price),
            "chainId": 0
        }
        create2factory = get_contract_instance(
            abi_file=os.path.join(file_dir,
                                  "contracts/create2factory_abi.json"),
            bytecode_file=os.path.join(
                file_dir, "contracts/create2factory_bytecode.dat"),
        )
        raw_create = create2factory.constructor().buildTransaction(
            self.tx_conf)
        tx_data = decode_hex(raw_create["data"])
        tx_create = create_transaction(pri_key=genesis_key,
                                       receiver=b'',
                                       nonce=nonce,
                                       gas_price=gas_price,
                                       data=tx_data,
                                       gas=gas,
                                       value=0,
                                       storage_limit=1920)
        nonce += 1
        self.rpc.send_tx(tx_create, True)
        receipt = self.rpc.get_transaction_receipt(tx_create.hash_hex())
        create2factory_addr = receipt['contractCreated']

        # Clear admin by non-admin (fail)
        self.log.info("Test unable to clear admin by non-admin.")
        set_admin = admin_control_contract.functions \
            .setAdmin(Web3.toChecksumAddress(create2factory_addr), null_addr) \
            .buildTransaction({"to":admin_control_contract_addr, **self.tx_conf})
        tx_data = set_admin["data"]
        self.call_contract(test_account_addr, test_account_key,
                           admin_control_contract_addr, tx_data)
        assert_equal(self.rpc.get_admin(create2factory_addr), genesis_addr)

        clear_admin_test_contract = get_contract_instance(
            abi_file=os.path.join(file_dir,
                                  "contracts/clear_admin_at_creation.json"),
            bytecode_file=os.path.join(
                file_dir, "contracts/clear_admin_at_creation.bytecode"),
        )

        self.log.info("Test contract creation by itself")
        raw_create = clear_admin_test_contract.constructor().buildTransaction(
            self.tx_conf)
        tx_data = decode_hex(raw_create["data"])
        tx_create = create_transaction(pri_key=genesis_key,
                                       receiver=b'',
                                       nonce=nonce,
                                       gas_price=gas_price,
                                       data=tx_data,
                                       gas=gas,
                                       value=0,
                                       storage_limit=1920)
        nonce += 1
        self.rpc.send_tx(tx_create, True)
        receipt = self.rpc.get_transaction_receipt(tx_create.hash_hex())
        address = receipt["contractCreated"]
        self.log.info("  contract created at %s" % address)
        assert (address is not None)

        self.log.info(
            "Test clear admin at contract creation through create2factory")
        create_data = raw_create["data"]
        salt = 0
        data = create2factory.functions.deploy(create_data,
                                               salt).buildTransaction({
                                                   "to":
                                                   create2factory_addr,
                                                   **self.tx_conf
                                               })["data"]
        # Compute the contract address.
        clear_admin_test_contract_addr = Web3.toChecksumAddress(
            "0x" + self.rpc.call(create2factory_addr, data)[-40:])
        # Deploy the contract.
        self.call_contract(genesis_addr,
                           genesis_key,
                           create2factory_addr,
                           data,
                           value=0)
        assert_equal(self.rpc.get_admin(clear_admin_test_contract_addr),
                     null_addr)
        # The owner of create2factory_addr isn't hijacked.
        self.log.info("Test unable to hijack set admin.")
        assert_equal(self.rpc.get_admin(create2factory_addr), genesis_addr)

        self.log.info(
            "Test unable to hijack owner through deployAndHijackAdmin")
        # Create a new contract through deployAndHijackAdmin.
        new_contract_to_deploy = get_contract_instance(
            abi_file=os.path.join(file_dir, "contracts/blackhole.json"),
            bytecode_file=os.path.join(file_dir,
                                       "contracts/blackhole.bytecode"),
        )
        self.tx_conf["nonce"] = 1
        self.tx_conf["from"] = Web3.toChecksumAddress(test_account_addr)
        new_raw_create = new_contract_to_deploy.constructor().buildTransaction(
            self.tx_conf)
        create_data = new_raw_create["data"]
        data = clear_admin_test_contract.functions.deployAndHijackAdmin(
            create_data).buildTransaction({
                "to": clear_admin_test_contract_addr,
                **self.tx_conf
            })["data"]
        new_contract_addr = "0x" + self.rpc.call(
            clear_admin_test_contract_addr, data)[-40:]
        self.call_contract(test_account_addr,
                           test_account_key,
                           clear_admin_test_contract_addr,
                           data,
                           value=123)
        # Check owner of the new contract isn't the "evil address" or null address.
        assert_equal(self.rpc.get_admin(new_contract_addr), test_account_addr)

        self.log.info("Pass")

    def call_contract(self,
                      sender,
                      priv_key,
                      contract,
                      data_hex,
                      value=0,
                      storage_limit=10000,
                      gas=CONTRACT_DEFAULT_GAS):
        c0 = self.rpc.get_collateral_for_storage(sender)
        tx = self.rpc.new_contract_tx(receiver=contract,
                                      data_hex=data_hex,
                                      sender=sender,
                                      priv_key=priv_key,
                                      value=value,
                                      storage_limit=storage_limit,
                                      gas=gas)
        assert_equal(self.rpc.send_tx(tx, True), tx.hash_hex())
        receipt = self.rpc.get_transaction_receipt(tx.hash_hex())
        self.log.info("call_contract storage collateral change={}".format(
            (self.rpc.get_collateral_for_storage(sender) - c0) //
            COLLATERAL_UNIT_IN_DRIP))
        return receipt
コード例 #2
0
    def run_test(self):
        file_dir = os.path.dirname(os.path.realpath(__file__))

        pay_contract = get_contract_instance(
            abi_file=os.path.join(file_dir, "contracts/pay_abi.json"),
            bytecode_file=os.path.join(file_dir, "contracts/pay_bytecode.dat"),
        )

        control_contract_file_path =os.path.join(file_dir, "../internal_contract/metadata/AdminControl.json")
        control_contract_dict = json.loads(open(control_contract_file_path, "r").read())

        admin_control_contract = get_contract_instance(contract_dict=control_contract_dict)

        start_p2p_connection(self.nodes)

        self.log.info("Initializing contract")
        genesis_key = self.genesis_priv_key
        genesis_addr = self.genesis_addr
        self.log.info("genesis_addr={}".format(encode_hex_0x(genesis_addr)))
        nonce = 0
        gas_price = 1
        gas = CONTRACT_DEFAULT_GAS
        block_gen_thread = BlockGenThread(self.nodes, self.log)
        block_gen_thread.start()
        self.tx_conf = {"from":Web3.toChecksumAddress(encode_hex_0x(genesis_addr)), "nonce":int_to_hex(nonce), "gas":int_to_hex(gas), "gasPrice":int_to_hex(gas_price), "chainId":0}

        # Setup balance for node 0
        node = self.nodes[0]
        client = RpcClient(node)
        (addr, priv_key) = client.rand_account()
        self.log.info("addr=%s priv_key=%s", addr, priv_key)
        tx = client.new_tx(value=5 * 10 ** 18, receiver=addr, nonce=self.get_nonce(genesis_addr))
        client.send_tx(tx, True)
        assert_equal(client.get_balance(addr), 5000000000000000000)

        (addr2, priv_key2) = client.rand_account()
        self.log.info("addr2=%s priv_key2=%s", addr2, priv_key2)
        tx = client.new_tx(value=5 * 10 ** 18, receiver=addr2, nonce=self.get_nonce(genesis_addr))
        client.send_tx(tx, True)
        assert_equal(client.get_balance(addr2), 5000000000000000000)

        # deploy pay contract
        tx = self.call_contract_function(
            contract=pay_contract,
            name="constructor",
            args=[],
            sender_key=priv_key,
            storage_limit=512)
        contract_addr = self.wait_for_tx([tx], True)[0]['contractCreated']
        self.log.info("contract_addr={}".format(contract_addr))
        assert_equal(client.get_collateral_for_storage(addr), 512 * 976562500000000)
        assert_equal(client.get_balance(contract_addr), 0)

        # deposit 10**18
        b0 = int(node.cfx_getBalance(addr), 16)
        tx = self.call_contract_function(
            contract=pay_contract,
            name="recharge",
            args=[],
            sender_key=priv_key,
            contract_addr=contract_addr,
            value=10 ** 18,
            wait=True,
            check_status=True)
        assert_equal(client.get_balance(contract_addr), 10 ** 18)
        assert_equal(client.get_balance(addr), b0 - 10 ** 18 - charged_of_huge_gas(gas))
        assert_equal(client.get_admin(contract_addr), addr)

        # transfer admin (fail)
        tx = self.call_contract_function(
            contract=admin_control_contract,
            name="setAdmin",
            args=[Web3.toChecksumAddress(contract_addr), Web3.toChecksumAddress(addr2)],
            sender_key=priv_key2,
            contract_addr=Web3.toChecksumAddress("0x0888000000000000000000000000000000000000"),
            wait=True,
            check_status=True)
        assert_equal(client.get_admin(contract_addr), addr)
        assert_equal(client.get_balance(addr2), 5 * 10 ** 18 - charged_of_huge_gas(gas))

        # transfer admin (success)
        tx = self.call_contract_function(
            contract=admin_control_contract,
            name="setAdmin",
            args=[Web3.toChecksumAddress(contract_addr), Web3.toChecksumAddress(addr2)],
            sender_key=priv_key,
            contract_addr=Web3.toChecksumAddress("0x0888000000000000000000000000000000000000"),
            wait=True,
            check_status=True)
        assert_equal(client.get_admin(contract_addr), addr2)

        # destroy
        b0 = client.get_balance(addr)
        tx = self.call_contract_function(
            contract=admin_control_contract,
            name="destroy",
            args=[Web3.toChecksumAddress(contract_addr)],
            sender_key=priv_key2,
            contract_addr=Web3.toChecksumAddress("0x0888000000000000000000000000000000000000"),
            wait=True,
            check_status=True)
        assert_equal(client.get_balance(contract_addr), 0)
        assert_equal(client.get_balance(addr2), 6 * 10 ** 18 - charged_of_huge_gas(gas) * 2)
        assert_equal(client.get_collateral_for_storage(addr), 0)
        assert_equal(client.get_balance(addr), b0 + 512 * 976562500000000)

        self.log.info("Pass")
コード例 #3
0
    def run_test(self):
        file_dir = os.path.dirname(os.path.realpath(__file__))

        pay_contract = get_contract_instance(
            abi_file=os.path.join(file_dir, "contracts/pay_abi.json"),
            bytecode_file=os.path.join(file_dir, "contracts/pay_bytecode.dat"),
        )

        admin_control_contract = get_contract_instance(
            abi_file=os.path.join(file_dir, "contracts/admin_control_abi.json"),
            bytecode_file=os.path.join(file_dir, "contracts/admin_control_bytecode.dat"),
        )

        start_p2p_connection(self.nodes)

        self.log.info("Initializing contract")
        genesis_key = self.genesis_priv_key
        genesis_addr = self.genesis_addr
        self.log.info("genesis_addr={}".format(encode_hex_0x(genesis_addr)))
        nonce = 0
        gas_price = 1
        gas = 50000000
        block_gen_thread = BlockGenThread(self.nodes, self.log)
        block_gen_thread.start()
        self.tx_conf = {"from":Web3.toChecksumAddress(encode_hex_0x(genesis_addr)), "nonce":int_to_hex(nonce), "gas":int_to_hex(gas), "gasPrice":int_to_hex(gas_price), "chainId":0}

        # Setup balance for node 0
        node = self.nodes[0]
        client = RpcClient(node)
        (addr, priv_key) = client.rand_account()
        self.log.info("addr=%s priv_key=%s", addr, priv_key)
        tx = client.new_tx(value=5 * 10 ** 18, receiver=addr, nonce=self.get_nonce(genesis_addr))
        client.send_tx(tx, True)
        assert_equal(client.get_balance(addr), 5000000000000000000)

        (addr2, priv_key2) = client.rand_account()
        self.log.info("addr2=%s priv_key2=%s", addr2, priv_key2)
        tx = client.new_tx(value=5 * 10 ** 18, receiver=addr2, nonce=self.get_nonce(genesis_addr))
        client.send_tx(tx, True)
        assert_equal(client.get_balance(addr2), 5000000000000000000)

        # deploy pay contract
        tx = self.call_contract_function(
            contract=pay_contract,
            name="constructor",
            args=[],
            sender_key=priv_key)
        contract_addr = self.wait_for_tx([tx], True)[0]['contractCreated']
        self.log.info("contract_addr={}".format(contract_addr))
        assert_equal(client.get_balance(contract_addr), 0)

        # deposit 10**18
        b0 = int(node.cfx_getBalance(addr), 16)
        tx = self.call_contract_function(
            contract=pay_contract,
            name="recharge",
            args=[],
            sender_key=priv_key,
            contract_addr=contract_addr,
            value=10 ** 18,
            wait=True,
            check_status=True)
        assert_equal(client.get_balance(contract_addr), 10 ** 18)
        assert_equal(client.get_balance(addr), b0 - 10 ** 18 - gas + gas // 4)
        assert_equal(client.get_admin(contract_addr), addr)

        # transfer admin (fail)
        tx = self.call_contract_function(
            contract=admin_control_contract,
            name="set_admin",
            args=[Web3.toChecksumAddress(contract_addr), Web3.toChecksumAddress(addr2)],
            sender_key=priv_key2,
            contract_addr=Web3.toChecksumAddress("0x6060de9e1568e69811c4a398f92c3d10949dc891"),
            wait=True,
            check_status=True)
        assert_equal(client.get_admin(contract_addr), addr)

        # transfer admin (success)
        tx = self.call_contract_function(
            contract=admin_control_contract,
            name="set_admin",
            args=[Web3.toChecksumAddress(contract_addr), Web3.toChecksumAddress(addr2)],
            sender_key=priv_key,
            contract_addr=Web3.toChecksumAddress("0x6060de9e1568e69811c4a398f92c3d10949dc891"),
            wait=True,
            check_status=True)
        assert_equal(client.get_admin(contract_addr), addr2)

        # destroy
        tx = self.call_contract_function(
            contract=admin_control_contract,
            name="destroy",
            args=[Web3.toChecksumAddress(contract_addr)],
            sender_key=priv_key2,
            contract_addr=Web3.toChecksumAddress("0x6060de9e1568e69811c4a398f92c3d10949dc891"),
            wait=True,
            check_status=True)
        assert_equal(client.get_balance(contract_addr), 0)
        assert_equal(client.get_balance(addr2), 5999999999912500000 + gas // 4)

        self.log.info("Pass")