Search code examples
transactionssolidity

how to send a transaction with encoded data from within a solidity smart contract


I want to send a transaction from my solidity smart contract to another smart contract, and all the actions are already encoded

Ex(0x7a1eb1b9000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a 0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000a0000 0000000000000000000000000000000000000000000056bc75e2d631000000000000000000000000000000000000000000000000009b1ea631e125f) which means swap token for a specific token (not exactly just an example)

But I don’t see any way of sending a transaction from a solidity smart contract with already encoded data, all examples show how to send the transaction by calling functions in the other smart contract

And I don’t want to decode my encoded data

I know how to do it using ethers.js like the example below:

const transaction = {
data:`0x7a1eb1b9000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000056bc75e2d63100000000000000000000000000000000000000000000000009b1ea631e125f`,  
to: Contract address,  
value: 0,  
from: my address,  
gasPrice: 21000,  
gasLimit: 4000000. 
    };   
const wallet = new ethers.Wallet(Address);  
const connectedWallet = wallet.connect(provider);  
const tx = await connectedWallet.sendTransaction(transaction);  

the "data" has all the actions I want to do, I want to do the same thing using solidity, is there a way?

Thank you for your help and time


Solution

  • You can use the low-level .call() method, member of the address type.

    The data field is required (you can pass an empty value if it fits your use case).

    Optional value sends along the specified ETH value (note that your contract needs to hold at least this amount or have to just have received it with this function call). And the optional gas is the max amount of gas units passed along to this specific call (and its subsequent calls).

    As your contract always acts as the caller (in other words, your contract address is the msg.sender in the called contract), you cannot set an arbitrary from field value. gasPrice is also static for the whole main transaction and cannot be changed for subsequent calls.

    function callAnotherContract() external {
        address anotherContract = address(0x123);
        bytes memory data = hex"7a1eb1b900";
        uint256 myValue = 0;
        uint256 myGasLimit = 100000;
    
        // data is required (can be empty), other params are optional
        anotherContract.call{value: myValue, gas: myGasLimit}(data);
    }
    

    Docs: