3

First, I'm aware of a similar question, but that answer is not sufficient.

Say I deployed an contract A, then I deploy another contract B some time later. I want to make sure that a function A.f1() in A can only be called from contract B. To do so, I implement a function register(address trusted_contract) to register B to A, which basically stores B's address to an array in A.. Since I own A, I'm the only one who can call it to register an address.

Now if B calls A.f1(), then within f1(), I check if msg.sender is in the array and decide if to serve the call.

Is this the right way to do it?

If it is, I still have a questions. What prevent another contract C to send a msg and claims that it is B? My understanding is that unlike an external account, a contract does not have a private key and thus can not sign a message. If so, how does receiver A verify the caller is contract B, not some bad actor C?

1

Is this the right way to do it?

Yes, except instead of an array you should use a map for efficient look up.

If so, how does receiver A verify the caller is contract B, not some bad actor C?

There are 2 ways an "attacker" can act:

  1. Send a transaction directly to your contract A.
  2. Send a transaction to some contract X (different from contract B), then inside the contract X a message call will be made to your contact A.

Inside the contract A two properties will be available:

  • tx.origin - the external account address.
  • msg.sender - the external account address for case 1; address of contract X for case 2.

msg.sender is what you will be checking to verify that the call is made from contract B.

In both cases the "attacker" can't fake to be contract B:

  • for the 1st case he would need to sign the transaction with the private key of contract B which does't exist;
  • for the 2nd case he doesn't have control over msg.sender because it's handled by the EVM: when a message call is made from contract X, the EVM must set the msg.sender to be the address of contract X.

So unless the "attacker" sends the transaction to contract B there will be no way for him to fake to be contract B.

  • Thank you! What in my mind was attack 2, and what you said cleared up my doubts. "he doesn't have control over msg.sender because it's handled by the EVM"! – user3839198 Feb 1 '18 at 20:46
0

Yes that is correct. What prevents an account from sending a transaction as contract B is that the account would need the private/public keypair to sign the transaction under the identity of the contract.

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.