ilanD
June 8, 2020, 11:51am
1
Open zeppelin contracts have this solution for ‘isContract’ modifier
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.2;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
This file has been truncated. show original
Implementation is based on EIP 1052 which seems not to be merged to the EVM yet.
---
eip: 1052
title: EXTCODEHASH opcode
author: Nick Johnson <arachnid@notdot.net>, Paweł Bylica <pawel@ethereum.org>
discussions-to: https://ethereum-magicians.org/t/extcodehash-opcode/262
status: Final
type: Standards Track
category: Core
created: 2018-05-02
requires: 161
---
## Abstract
This EIP specifies a new opcode, which returns the keccak256 hash of a contract's code.
## Motivation
Many contracts need to perform checks on a contract's bytecode, but do not necessarily need the bytecode itself. For instance, a contract may want to check if another contract's bytecode is one of a set of permitted implementations, or it may perform analyses on code and whitelist any contract with matching bytecode if the analysis passes.
Contracts can presently do this using the `EXTCODECOPY` opcode, but this is expensive, especially for large contracts, in cases where only the hash is required. As a result, we propose a new opcode, `EXTCODEHASH`, which returns the keccak256 hash of a contract's bytecode.
This file has been truncated. show original
Should this code be used in production code at all?
Still I see a warning in this that it will return false for the case that
“* - a contract in construction”
So it can’t be used for onlyNonContract modifier.
In below article it is advised to use tx.origin for checking if a call is originating from a contract or non-contract address.
https://consensys.github.io/smart-contract-best-practices/recommendations/#avoid-using-extcodesize-to-check-for-externally-owned-accounts
But from other reads and best practices, it seems tx.origin might be deprecated at some stage.
Although there is no clear statement about that.
please advise how to create an onlyNonContract modifier.
thanks
1 Like
Hi @ilanD ,
For an onlyNonContract
your options appear to be:
I assume it comes down to your use case in what you are trying to prevent and if the option covers this (including any caveats on what it can detect/prevent).
I had a look through the Solidity issues to see if I could find discussions on potentially deprecating tx.origin. I only found this issue: https://github.com/ethereum/solidity/issues/683
ilanD
June 9, 2020, 12:03pm
3
Seems that isContract(address account) will not protect from calls from a contracts ctor.
thus will not give the required protection.
1 Like
Indeed, isContract
can only be used to assert that an address is a contract, and should never be used to assert that an address is not a contract.
There is relevant discussion in Bypassing Smart Contract Timelocks . An alternative method proposed there is to require a signature from the address in order to verify that it is an EOA, and thus conclude it isn’t a contract.
1 Like