It is possible to sign a transaction with a smart contract ?, i thinking not

Hello everyone i have question about it is possible to call a smart contract with other smart contract, i the lastest days i have a technical interview and the problem says the next :

"and should allow only Smart Contracts to claim the reimbursement."

i trying do that using the unit test in hardhat but is interesting because you can do it if you use a “call” function from a smart contract using the address, but you can’t sign ( send ) transactions with a smart contract in hardhat to test that

the question that i have in this days if is possible to do that, of course i fail the technical interview but i still thinking the only way that anyone can do that is calling the function with another smart contract inside solidity and not with web3 in a test with hardhat and the task says i need to integrate the test to check if i am doing right the things, but for me thats no make sense because you can’t sign transactions with a smart contract and if i cant do that i never pass the task because is needed test the logic :face_with_raised_eyebrow: :sob:

1 Like

Hi @ismael_zamora,

Yes… but the transaction itself still has to start by being signed and sent by an external address. The transaction can start with an external call from a web3 client to a smart contract function, which in turn calls other functions, and which can include external function calls — calls from one contract to a function in another. These calls between contracts aren’t signed, because they are still part of the same transaction, but the called contract can still validate the call before acting on it by using require statements to check the calling contract’s address and input values, for example.

How far have you actually got with your Solidity studies? I’m asking, because you need to have at least acquired all of the knowledge from this 101 course, and probably most of 201 as well, before you’ll be able to fully understand how this works, and how you can implement smart contracts which perform the sort of task from the interview you’ve mentioned.

You’ll need a knowledge of how to perform external function calls capable of sending Ether value, interfaces, and probably inheritance too. So unless you already have that knowledge and experience, it’ll take a very long time to explain :wink:

In terms of the scenario you mention of a smart contract claiming a reimbursement, this really could be interpreted in different ways depending on the specifics of the actual use case… e.g. The user might send a transaction requesting a refund; the smart contract processes the request, but instead of sending the refund directly to the user’s address, it sends it to a separate smart contract, where it is held until the user withdraws it (in a separate transaction). Or the user might send a transaction to a different smart contract, requesting the smart contract itself to call another smart contract with a refund request. The smart contract issuing the refund could validate and process the refund based on the address of the external contract, and not the user’s external address, so in that sense it will be the smart contract address “claiming” the reimbursement.

As you can see, the different variations are endless. But, essentially, they all involve knowledge of the same set of smart-contract coding concepts and techniques, which you need to learn fully first. :muscle: :slight_smile:

1 Like

Hello @jon_m , thanks for read and write :slight_smile:

but the transaction itself still has to start by being signed and sent by an external address

may be i have a idea how the task it is, in general if you use the function that call another function and pass the address of the first contract may be you can check if the caller of the function is really a contract or not for example :

ContractB => function ( address _whoCalls ) => ContractA use the function of ContractB

and in _whoCalls is the address(this), so before run the function in contractB you can check if is really smart contract the caller, for example using this function that i find in stack overflow using assembly :

function isContract(address addr) returns (bool) {
  uint size;
  assembly { size := extcodesize(addr) }
  return size > 0;
}

i never know if that go na be the solution because i fail the technical interview but i think it is possible to check inside the code who exacly calls the function

How far have you actually got with your Solidity studies? I’m asking, because you need to have at least acquired all of the knowledge from this 101 course, and probably most of 201 as well, before you’ll be able to fully understand how this works, and how you can implement smart contracts which perform the sort of task from the interview you’ve mentioned.

i really dont know how much exacly i know because i start in 2019 to learn somethings but in all this time i have to develop in many areas like a fullstack so i dont know much in deep i think, thats the cause of why i cant pass the interview obviusly but is a good feel testing my self to see if i have the capacity to solve problems

In terms of the scenario you mention of a smart contract claiming a reimbursement, this really could be interpreted in different ways depending on the specifics of the actual use case… e.g. The user might send a transaction requesting a refund;

yes but the question that i have this lastest days is why the task says :

only Smart Contracts to claim the reimbursement

outside this rule i have multiple ideas to how to solve, but i thinking if they are saying only smart contracts can claim, if you claim with a account you are not exacly claim her with a smart contract because is a account, so i only i assume this lastest days when they says claim only with smart contract is similar that i explained ( internally only one contract can call another contract to claim the reimbursment ) because the caller of the function outside solidity ( using web3 ) is only from an account

i really don’t know why i am thinking this yet but is interestig how a little descriptions in a task can say much things and can be interpretated for many cases

As you can see, the different variations are endless. But, essentially, they all involve knowledge of the same set of smart-contract coding concepts and techniques, which you need to learn fully first

thats correct :heart:

i thinking i know much things but i need to put that in practice, nothing better than failing and learning from it :smiley:

Thanks for read and answer, grettings from Chile ! :heart:

Hello again :slight_smile: , I can’t edit my lastest post but here an example of know who address call the function :

i have two files

ContratoA.sol ( ContractA )
ContratoB.sol ( ContractB )

ContratoA.sol ( ContractA ) :

pragma solidity ^0.8.0;

interface ContratoB {

    function getData() external view returns(address);

}

contract ContratoA {

    ContratoB contratoB;

    constructor(address _myContractB){
        contratoB = ContratoB(_myContractB);
    }

    function get() public view returns(address _whoCalls) {
        return contratoB.getData();
    }

}

ContratoB.sol ( ContractB ) :

pragma solidity ^0.8.0;

contract ContratoB {

    modifier onlyContracts(){
        require(isContract(msg.sender) == true,'Only for Smart Contracts');
        _;
    }
    
    function isContract(address addr) private view returns (bool) {
        uint size;
        assembly { size := extcodesize(addr) }
        return size > 0;
    }
    
    function getData() external view onlyContracts returns(address) {
        return (msg.sender);
    }

}

Here are the address of the deploy :
image

Here is my actual address account :
image

Case 1
so if i call the function from the ContractA i see this
( in this case the Contract call the function of B ) :
image

Case 2
but if i try to run the function from the ContractB
(nothing happends because the caller is not a smart contract )
image
image
image

this is how can be called from another contract

Grettings from Chile :slight_smile: :heart:

1 Like

Hey Ismael!

Yes, this is the basic idea — well done :ok_hand:

Yes, that’s essentially correct, but as you’ve demonstrated in your code, the calling contract (A) will be msg.sender, so you can just perform your validation checks in contract B using msg.sender instead of having to pass the calling address as a parameter.

You also don’t need   == true   in your modifier’s require() statement, because the Boolean returned from isContract() is enough for the require() statement to generate the correct outcome …

require(isContract(msg.sender), "Only for Smart Contracts");

/*   true   =>  fx executed                                                    */
/*   false  =>  fx reverts & error message: Only for Smart Contracts           */
/*   We don't need to evaluate:
      true == true   =>  true
      false == true  =>  false
                                                                               */

So, yes … msg.sender in the called contract (B) will be the calling contract address (A).

That’s a great bit of research :ok_hand: But you may not need it if the function called in contract (B) requires certain inputs that can only come from another contract such as contract A… Again, it all depends on your particular scenario.

Next, you want to look at how to get the function in contract B to send funds (e.g. a reimbursement) to contract A, but only if the external call from A meets certain requirements. This should result in contract A storing these funds on behalf of the user, who can then call contract A to withdraw them afterwards.

I think you will benefit a lot from working through the Solidity courses, as this will be a good way for you to check how much you already know, consolidate this, discover where the gaps in your knowledge are, fill those in, and then continue learning more advanced techniques. I would suggest first taking Ethereum Smart Contract Programming 101 and then the 201 course. After that you can do the following two courses in the order you feel will benefit you the most:

  • Ethereum Smart Contract Security Course (focuses on security issues and solutions)
  • Ethereum Dapp Programming (involves developing both the backend and the frontend i.e. full stack)

Yes… it’s great you are using it as a learning experience. I agree it’s a great way to test your knowledge and discover what it is you are aiming for :muscle:

Yes, but as I think you’ve already undertsood, any transaction has to start with an external account signing and sending that transaction. So, a user will always be the initiator of a transaction, but the transaction can instruct a smart contract to perform operations on the user’s behalf e.g. requesting and claiming a reimbursement from another smart contract. Think of it in terms of how limited companies or trusts work in finance: they are seperate legal entities which perform financial operations, but these operations still need to be authorised, signed-off and initiated by physical people.

Anyway, Ismael, you’re already making good progress! Keep up the great research! :smiley:

1 Like