2

I want to call contract A in contract B, like this:

contract  A{
    uint 256 a;
    function set(uint _a){ 
           require(a > 100);
           a = _a;

    }

}

contract B{
   function callA(){
   A a = A(the_addr_of_A);
   a.set(100);
   }
}

But how can I ensure a.set(100); is done correctly?

Since I have a require statement require(a > 100) in contract A, a.set(100) will not work, can contract B notice that?

3

Yes, because B is calling A's function a. The whole transaction will revert as a result of this.

If you don't want the whole transaction to revert, you'll have to use address.call like in contract C below.

pragma solidity 0.4.24;

contract  A{
    uint256 a;
    function set(uint _a) public { 
        require(_a > 100);
        a = _a;
    }

}

contract C {
    function callA(A _a, uint256 _value) public {
        bool success = address(_a).call(abi.encodeWithSignature("set(uint256)", _value));
        emit ACalled(success);
    }

    event ACalled(bool success);
}

Please note that you had a couple of typos in your code.

First deploy A using remix or something, then deploy C. When both are deployed, call C.callA. First with value 100, then with value 101. You'll notice the difference in the transaction logs. Success will be false with 100, but true with 101.

Be careful using address.call

Make sure only addresses of contracts you trust are called.

  • Thakn you very much! – Yuan Rui Aug 15 '18 at 7:52

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.