0

The below screenshot is from Andreas' book. I don't understand why this programming technique is so risky. See the text in the red block in the image.

enter image description here

We have the .sol file, and the Bytecode on the Blockchain at the contract address is immutable. Can't we verify that the Contract Bytecode matches the Bytecode generated by the provided .sol file, hence, this would eliminate any risk?

Thank you

0

It's a misleading description in my opinion. It seems to conflate two different concerns.

Firstly, one can use an address or a contract instance in the arguments. The latter is more type-safe at the compiler level and that can possibly help catch developer errors.

For example

constructor(Faucet f) ...

which is still an address, externally but is already cast as an instance of Faucet.

Great, but that doesn't mean the received address is indeed a faucet, nor does it confirm the expected functions exist or that they are trustworthy.

You can approximate trustworthiness with a simple heuristic. Either the contract is part of our system or it is suspect. As shown, it would be possible to manually (or with a deployment script) pass the faucet address in and be done with it. That externalizes a vital concern and nothing in the contract code guards against error or oversight. The intended binding of the two contracts could be coded into the contracts themselves.

Assuming the simple case where faucet and token are paired 1:1, the faucet could deploy the token.

contract Faucet {

  Token token;

  constructor() public {
     token = new Token();
    ...

contract Token {

  Faucet faucet;

  constructor () public {
     faucet = Faucet(msg.sender);

When you deploy only the faucet you will get two contracts with reliable awareness of their counterpart addresses and you can use that to gaurd sensitive functions by checking that msg.sender is the trusted address.

Hope it helps.

  • constructor(Faucet f) ... But with this design technique f only lives within the Scope of the Constructor no? I want f to be accessible throughout the contract. Also in your second example I would deploy both contracts. The use case I was after was interacting with another developer's already deployed contract. – Picard78 Oct 4 '20 at 6:07
  • To your first point, assign f to a state variable. I left out Faucet faucet ... faucet = f to keep it short. – Rob Hitchens Oct 5 '20 at 2:41
  • Your second point touches on trust. The type-safe style provides some protection from internal developer error. It does nothing to ensure that ensure the address passed in actually implements the expected functions or works as expected. That passage seems to imply that it's way better but actually not much better when talking to strangers. – Rob Hitchens Oct 5 '20 at 2:46
  • We can further categorize external actors. There are those that are already published, are understood and are not subject to arbitrary (unwelcome?) changes. For example, a swap system you want to work with. You could pass in a type-safe interface. – Rob Hitchens Oct 5 '20 at 2:50
  • But, some applications might invite the user to supply a contract address such as a token. This is very dangerous because unknkwn contracts, not necessarily friendly can do things you might not agree with. That sort of concern is not addressed, at all, by the choice of address or contract type casting. – Rob Hitchens Oct 5 '20 at 2:53

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.