After executing this transaction, the Relayers network will transfer 1e18 of the target network's native tokens to the recipient's address.
Sending Transactions to a Smart Contract
Sending transactions to an arbitrary smart contract makes sense when the called method does not depend on the msg.sender address. For example, the address is passed in the arguments, or it involves meta-transactions or account abstraction.
For example, a standard transaction within one network:
sender.sendTransaction({
from: sender.address, // sender
to: smartContract.address, // called smart contract
value: 0, // amount of funds sent
data: '0x11111...' // encoded transaction
})
To deliver a similar transaction to another network, it looks like this:
By executing this transaction, the YarResponse smart contract will parse the bytes from data and call the specified function at the target address. You can also pass the value parameter with this transaction if needed.
Here's the English translation of the provided Russian text, formatted for a programming context:
Cross-Chain API
The main potential of the Yar protocol lies in enabling communication between smart contracts of the same application located on different networks.
Create an empty smart contract:
contract Example {
}
Register the addresses of [YarRequest] and [YarResponse] in the smart contract:
contract Example {
address public yarRequest;
address public yarResponse;
constructor(
address initialYarRequest,
address initialYarResponse
) {
yarRequest = initialYarRequest;
yarResponse = initialYarResponse;
}
}
To send a cross-chain transaction from a smart contract, the [YarRequest] will require the data model [YarLib.YarTX].
library YarLib {
struct YarTX {
uint256 initialChainId; // Identifier of the current network
address sender; // Your smart contract [Example]
address payer; // User who calls Example and pays the fee in Yar
uint256 targetChainId; // Identifier of the network where the transaction will be delivered
address target; // Address in the [TARGET] network where the transaction will be called
uint256 value; // Amount of the native token of the [TARGET] network to be sent with the transaction
bytes data; // Encoded transaction data (bytes4 for the function signature + function arguments)
uint256 _nonce; // This parameter will be redefined in YarRequest; set it to 0
}
}
Import YarLib into your smart contract:
import { YarLib } from "./YarLib.sol";
contract Example {
...
}
Develop a receiver function that will accept a string of data. Two checks are required to identify the senders:
Check that msg.sender equals the yarResponse address.
Check that yarTX.sender equals the address of your smart contract from the initial network.
contract Example {
string public lastMessage;
function exampleReceiveMessage(string calldata message) external {
require(msg.sender == yarResponse, "only yarResponse!");
YarLib.YarTX memory yarTx = YarResponse(yarResponse).trustedYarTx();
// Check against address(this)
// - This will work if both smart contracts have the same address
// If your smart contracts have different addresses, you will need to register them separately
require(yarTx.sender == address(this), "only app!");
lastMessage = message;
}
}
Example of registering the addresses of your applications from external networks:
Now, to make this function callable from another network, implement a message-sending function.
contract Example {
function exampleSendMessage(
string calldata message,
uint256 targetChainId
) external returns(YarLib.YarTX) {
...
}
}
Where message is the message to be sent
targetChainId is the network where the message will be delivered
returns(YarLib.YarTX) is used in simulation for gas estimation.
Encode the call to the [exampleReceiveMessage] function:
YarLib.YarTX memory yarTx = YarLib.YarTX(
block.chainid,
address(this), // if your applications have identical addresses
msg.sender,
targetChainId,
targetAddress,
0,
encodedTX,
0
);
or
YarLib.YarTX memory yarTx = YarLib.YarTX(
block.chainid,
getPeer(targetChainId), // to get the address of your application in the target network
msg.sender,
targetChainId,
targetAddress,
0,
encodedTX,
0
);
Next, send this model to YarRequest:
contract Example {
function exampleSendMessage(
string calldata message,
uint256 targetChainId
) external returns(YarLib.YarTX) {
bytes memory encodedTX = abi.encodeWithSelector(
Example.exampleReceiveMessage.selector,
message
);
YarLib.YarTX memory yarTx = YarLib.YarTX(
block.chainid,
address(this), // if your applications have identical addresses
msg.sender,
targetChainId,
targetAddress,
0,
encodedTX,
0
);
// Send the transaction
// Returning the model can be useful for transaction simulation and fee estimation
return YarRequest(yarRequest).send(yarTX);
}
}
Now, for the user to send a transaction from one of your smart contracts to another in an external network, they must have a balance in YarHub.