diff --git a/components/quizzes/quizData.json b/components/quizzes/quizData.json index 35793a51..4e1d40a2 100644 --- a/components/quizzes/quizData.json +++ b/components/quizzes/quizData.json @@ -11,6 +11,10 @@ "interchain-token-transfer": { "title": "Interchain Token Transfer", "quizzes": ["118", "119", "120", "121", "122", "123", "124", "125", "126", "127"] + }, + "interchain-messaging": { + "title": "Interchain Messaging", + "quizzes": ["301", "302", "303", "304", "305", "306", "307", "308", "309", "310", "311", "312", "313", "314", "315", "316"] } }, "quizzes": { @@ -353,6 +357,246 @@ "correctAnswers": [0], "explanation": "Yes, there can be multiple TokenRemotes for a single TokenHome. This allows the same token to be bridged to multiple chains, enabling cross-chain interoperability and use cases across different blockchain networks.", "chapter": "Interchain Token Transfer" + }, + "301": { + "question": "What is the role of a message in cross-blockchain communication?", + "options": [ + "To process the data on the destination chain.", + "To contain source, destination, and encoded data with a signature.", + "To originate communication from the source chain.", + "To validate the message authenticity on the source chain." + ], + "correctAnswers": [ + 1 + ], + "hint": "Messages carry essential information between chains, including source and destination details.", + "explanation": "A message in cross-blockchain communication contains the source, destination, and encoded data along with a signature that guarantees its authenticity. This ensures that the information being transferred is accurate and can be trusted by the destination chain.", + "chapter": "Interchain Messaging" + }, + "302": { + "question": "How does a multi-chain system achieve greater scalability compared to single-chain networks?", + "options": [ + "By increasing the gas limit on a single chain.", + "By running independent chains in parallel, allowing for combined throughput.", + "By implementing more complex smart contracts on a single chain.", + "By reducing the number of validators in the network." + ], + "correctAnswers": [ + 1 + ], + "hint": "Multi-chain systems utilize parallelism to enhance overall network performance.", + "explanation": "A multi-chain system achieves greater scalability by running independent chains in parallel. This parallelism allows the network to handle a higher combined throughput of transactions, as each chain can process its own set of transactions simultaneously without being bottlenecked by a single chain's limitations.", + "chapter": "Interchain Messaging" + }, + "303": { + "question": "Which Solidity functions are used for encoding and decoding data?", + "options": [ + "serializeData() and deserializeData()", + "encodeData() and decodeData()", + "abi.encode() and abi.decode()", + "bytes.encode() and bytes.decode()" + ], + "correctAnswers": [ + 2 + ], + "hint": "These functions are part of Solidity's ABI encoding and decoding utilities.", + "explanation": "In Solidity, `abi.encode()` is used to encode data into a bytes array, and `abi.decode()` is used to decode a bytes array back into its original types. These functions are essential for handling complex data structures in smart contracts.", + "chapter": "Encoding & Decoding" + }, + "304": { + "question": "What is the name of the function used by a dApp to send a cross-chain message in the Interchain Messaging contract?", + "options": [ + "sendCrossChainMessage()", + "sendCrossMessage()", + "initiateCrossChainCommunication()", + "sendMessageCrossChain()" + ], + "correctAnswers": [ + 0 + ], + "hint": "This function is part of the ITeleporterMessenger interface used for sending messages between chains.", + "explanation": "The `sendCrossChainMessage()` function is used by dApps to send cross-chain messages through the Interchain Messaging contract. It takes a `TeleporterMessageInput` struct as input, which includes details such as the destination chain ID, destination address, fee information, required gas limit, allowed relayers, and the encoded message.", + "chapter": "Sending a Message" + }, + "305": { + "question": "Which interface must a contract implement to receive messages from the Interchain Messaging contract?", + "options": [ + "ITeleporterMessenger", + "ITeleporterReceiver", + "ITeleporterSender", + "IMessageHandler" + ], + "correctAnswers": [ + 1 + ], + "hint": "This interface defines the necessary function for receiving cross-chain messages.", + "explanation": "To receive messages from the Interchain Messaging contract, a contract must implement the `ITeleporterReceiver` interface. This interface requires the implementation of the `receiveTeleporterMessage` function, which handles incoming messages.", + "chapter": "Receiving a Message" + }, + "306": { + "question": "After encoding multiple values into a byte array using `abi.encode()`, what must you know to correctly decode the byte array in Solidity?", + "options": [ + "The length of the byte array", + "The contract's address", + "The types and order of the encoded values", + "The encoding algorithm used" + ], + "correctAnswers": [ + 2 + ], + "hint": "Decoding requires knowledge of the original data structure used during encoding.", + "explanation": "To accurately decode a byte array in Solidity using `abi.decode()`, you must know the exact types and the order in which the values were encoded. This ensures that each segment of the byte array is interpreted correctly back into its original form.", + "chapter": "Encoding & Decoding" + }, + "307": { + "question": "Why are `abi.encode()` functions called twice when encoding a function call with multiple parameters in a cross-chain message?", + "options": [ + "To increase the security of the message.", + "To pack the function name and its parameters into a single bytes array.", + "To separate the message into two distinct byte arrays.", + "To comply with the Teleporter contract requirements." + ], + "correctAnswers": [ + 1 + ], + "hint": "Encoding the function name alongside its parameters ensures proper identification and handling on the receiving end.", + "explanation": "Calling `abi.encode()` twice allows you to first encode the function parameters and then encode the function name along with the encoded parameters. This ensures that the receiving contract can decode the function name to determine which internal function to execute with the provided parameters.", + "chapter": "Encoding the Function Name and Parameters" + }, + "308": { + "question": "How does the TeleporterRegistry contract track different versions of the TeleporterMessenger contracts?", + "options": [ + "By maintaining an array of contract addresses.", + "By using separate variables for each version.", + "By maintaining a mapping of version numbers to contract addresses.", + "By storing all contract addresses in a single bytes array." + ], + "correctAnswers": [ + 2 + ], + "hint": "The registry uses a key-value structure to associate versions with their corresponding contract addresses.", + "explanation": "The TeleporterRegistry contract tracks different versions of the TeleporterMessenger contracts by maintaining a mapping of version numbers to their respective contract addresses. This allows cross-Avalanche L1 dApps to request either the latest version or a specific version of the TeleporterMessenger as needed.", + "chapter": "How the ICM Registry works" + }, + "309": { + "question": "What is the purpose of the `Recover` algorithm in some signature schemes?", + "options": [ + "To generate a key pair.", + "To sign a message using the private key.", + "To recover the public key from a message and its signature.", + "To verify the integrity of a message." + ], + "correctAnswers": [ + 2 + ], + "hint": "The `Recover` algorithm helps to retrieve the public key used to create a signature.", + "explanation": "The `Recover` algorithm is used to retrieve the public key that corresponds to the private key used to create the signature for a given message. This allows for verification of the signature by matching the recovered public key with the sender's public key, ensuring the authenticity and integrity of the message.", + "chapter": "Signature Schemes" + }, + "310": { + "question": "What is a key advantage of the BLS multi-signature scheme in blockchain applications?", + "options": [ + "It requires only one private key for all participants.", + "It eliminates the need for public keys.", + "It uses symmetric cryptography for enhanced security.", + "It supports signature and public key aggregation, resulting in compact signatures." + ], + "correctAnswers": [ + 3 + ], + "hint": "The BLS scheme is known for its ability to aggregate multiple signatures into one.", + "explanation": "The BLS (Boneh-Lynn-Shacham) multi-signature scheme is highly efficient for blockchain applications due to its support for both signature and public key aggregation. This means multiple signatures can be compressed into a single short signature, and multiple public keys can be aggregated into one, reducing the storage and transmission overhead while maintaining security and integrity.", + "chapter": "Signature Schemes" + }, + "311": { + "question": "What is the primary responsibility of the P-Chain in the Avalanche Network?", + "options": [ + "Overseeing validator registration and staking operations for Avalanche L1s.", + "Managing the execution of smart contracts.", + "Handling transactions on the X-Chain.", + "Facilitating the transfer of assets between different chains." + ], + "correctAnswers": [ + 0 + ], + "hint": "The P-Chain is responsible for validator and staking operations.", + "explanation": "In the Avalanche Network, the P-Chain is responsible for validator and Avalanche L1-level operations. This includes the creation of new blockchains and Avalanche L1s, the addition of validators to Avalanche L1s, staking operations, and other platform-level operations. By registering BLS public keys and managing staking, the P-Chain ensures the security and functionality of the network.", + "chapter": "P-Chain" + }, + "312": { + "question": "Which component is responsible for relaying interchain messages to the destination chain in the Avalanche Network?", + "options": [ + "Warp Precompile", + "Signature Verification", + "AWM Relayer", + "Message Initialization" + ], + "correctAnswers": [ + 2 + ], + "hint": "This component checks outgoing messages and delivers them to the destination chain.", + "explanation": "The **AWM Relayer** is responsible for relaying interchain messages to the destination chain. It periodically checks the source Avalanche L1 for outgoing messages and delivers these by calling the Interchain Messaging contract on the destination Avalanche L1. This ensures that messages are efficiently transmitted between chains.", + "chapter": "Data Flow of an Interchain Message" + }, + "313": { + "question": "How does the AWM Relayer in the Avalanche Network detect new outgoing messages?", + "options": [ + "By periodically polling the source chain or being triggered by notifications.", + "By receiving real-time alerts from validators.", + "By scanning transaction receipts on the destination chain.", + "By querying the latest block headers exclusively." + ], + "correctAnswers": [ + 0 + ], + "hint": "The AWM Relayer uses either a regular checking mechanism or event-based triggers.", + "explanation": "The AWM Relayer detects new outgoing messages by either polling the source Avalanche L1 periodically for new messages or being triggered by notifications whenever a new outgoing message is detected by a node. This dual approach ensures that messages are efficiently picked up and relayed to the destination chain.", + "chapter": "Message Pickup" + }, + "314": { + "question": "Why does the AWM Relayer not aggregate the BLS Public Keys off-chain and attach them to the message?", + "options": [ + "Because aggregating off-chain would increase the message size significantly.", + "To prevent the AWM Relayer from creating fraudulent public keys and signatures, ensuring security.", + "Because the destination chain does not support off-chain aggregation.", + "To reduce the computational load on the AWM Relayer." + ], + "correctAnswers": [ + 1 + ], + "hint": "Aggregating public keys off-chain could allow the relayer to fabricate signatures.", + "explanation": "The AWM Relayer does not aggregate the BLS Public Keys off-chain and attach them to the message to prevent security vulnerabilities. If aggregation were done off-chain, the relayer could create fake public keys and signatures, compromising the authenticity and integrity of the messages. By requiring each validator on the destination chain to perform the aggregation, the system ensures that the aggregated public key accurately represents the signing validators, maintaining trust and security in the cross-chain communication process.", + "chapter": "Signature Schemes" + }, + "315": { + "question": "What is the primary purpose of depositing ERC-20 tokens into the Interchain Messaging contract in the Avalanche Network?", + "options": [ + "To pay for gas fees associated with transactions.", + "To serve as collateral for staking operations.", + "To incentivize the AWM Relayer by providing a reward for delivering messages.", + "To lock tokens and prevent them from being transferred." + ], + "correctAnswers": [ + 2 + ], + "hint": "Depositing tokens serves as a financial incentive for relayers to perform their duties.", + "explanation": "Depositing ERC-20 tokens into the Interchain Messaging contract acts as a reward mechanism for the AWM Relayer. When a relayer successfully delivers a message, they can claim the deposited tokens as compensation for their efforts in ensuring reliable cross-chain communication. This incentivization helps maintain the efficiency and security of the messaging system.", + "chapter": "Fee Data Flow" + }, + "316": { + "question": "According to the Avalanche Network's fee incentivization model, how should the minimum fee amount be calculated to ensure that a Relayer makes at least a 10% profit?", + "options": [ + "Fee = requiredGasLimit * gas_price_in_native_token", + "Fee = (requiredGasLimit * gas_price_in_native_token) / 1.1", + "Fee = requiredGasLimit + gas_price_in_native_token + native_token_price", + "Fee = 1.1 * (requiredGasLimit * gas_price_in_native_token * native_token_price)" + ], + "correctAnswers": [ + 3 + ], + "hint": "The fee should cover the costs and provide additional profit to the Relayer.", + "explanation": "To ensure the Relayer makes at least a 10% profit, the fee amount should be calculated as 1.1 times the cost. The cost is determined by multiplying the requiredGasLimit by the gas price in native tokens and the native token price. Therefore, the minimum fee should be 1.1 * (requiredGasLimit * gas_price_in_native_token * native_token_price).", + "chapter": "Determining the Fee" } } } \ No newline at end of file diff --git a/content/course/interchain-messaging/02-interoperability/02-source-message-destination.mdx b/content/course/interchain-messaging/02-interoperability/02-source-message-destination.mdx index ff06e0e8..367faaaa 100644 --- a/content/course/interchain-messaging/02-interoperability/02-source-message-destination.mdx +++ b/content/course/interchain-messaging/02-interoperability/02-source-message-destination.mdx @@ -39,4 +39,6 @@ The message is the data structure that will be sent to to the destination chain. ## Destination Chain -Conversely, the destination chain is the recipient blockchain where the communicated data, assets, or instructions will be received and processed. Validators, nodes, or protocols associated with the cross-blockchain communication system on the destination chain receive and authenticate the information relayed from the source chain. Once validated, the destination chain processes the data or executes the specified instructions. \ No newline at end of file +Conversely, the destination chain is the recipient blockchain where the communicated data, assets, or instructions will be received and processed. Validators, nodes, or protocols associated with the cross-blockchain communication system on the destination chain receive and authenticate the information relayed from the source chain. Once validated, the destination chain processes the data or executes the specified instructions. + + diff --git a/content/course/interchain-messaging/02-interoperability/03-multi-chain-networks.mdx b/content/course/interchain-messaging/02-interoperability/03-multi-chain-networks.mdx index 6fcece5b..02fd8d2e 100644 --- a/content/course/interchain-messaging/02-interoperability/03-multi-chain-networks.mdx +++ b/content/course/interchain-messaging/02-interoperability/03-multi-chain-networks.mdx @@ -28,4 +28,6 @@ Different blockchain networks use different scaling approaches, such as Layer 2s ![](/common-images/multi-chain-architecture/combined-throughput.png) -While roll-ups may enable a very high-throughput of a single chain, they can never outcompete the combined throughput of a multi-chain system. This is because there's no limit to the number of chains that can run in parallel. \ No newline at end of file +While roll-ups may enable a very high-throughput of a single chain, they can never outcompete the combined throughput of a multi-chain system. This is because there's no limit to the number of chains that can run in parallel. + + \ No newline at end of file diff --git a/content/course/interchain-messaging/04-icm-basics/02-recap-bytes-encoding-decoding.mdx b/content/course/interchain-messaging/04-icm-basics/02-recap-bytes-encoding-decoding.mdx index 15df3606..3b06b068 100644 --- a/content/course/interchain-messaging/04-icm-basics/02-recap-bytes-encoding-decoding.mdx +++ b/content/course/interchain-messaging/04-icm-basics/02-recap-bytes-encoding-decoding.mdx @@ -49,4 +49,6 @@ When we decode data, we convert it from a byte array back into its original form ) = abi.decode(message, (string, uint)); ``` -This will give us back the original values that we encoded before. Note that we do need to know the types of the values and their order that we encoded to decode them correctly. \ No newline at end of file +This will give us back the original values that we encoded before. Note that we do need to know the types of the values and their order that we encoded to decode them correctly. + + \ No newline at end of file diff --git a/content/course/interchain-messaging/04-icm-basics/03-sending-a-message.mdx b/content/course/interchain-messaging/04-icm-basics/03-sending-a-message.mdx index 555b1e4a..e2372964 100644 --- a/content/course/interchain-messaging/04-icm-basics/03-sending-a-message.mdx +++ b/content/course/interchain-messaging/04-icm-basics/03-sending-a-message.mdx @@ -61,3 +61,5 @@ The `sendCrossChainMessage` function takes `TeleporterMessageInput` struct as an - **`requiredGasLimit`:** The amount of gas the delivery of the message requires. If the relayer provides the required gas, the message will be considered delivered whether or not its execution succeeds, such that the relayer can claim their fee reward. - **`allowedRelayerAddresses`:** An array of addresses of allowed relayers. An empty allowed relayers list means anyone is allowed to deliver the message. We will look at this later in more detail. - **`message`:** The message to be sent as bytes. The message can contain multiple encoded values. DApps using Interchain Messaging are responsible for defining the exact format of this payload in a way that can be decoded on the receiving end. The message can hold multiple values that be encoded in a single bytes object. For example, applications may encode multiple method parameters on the sending side, then decode this data in the contract implementing the receiveTeleporterMessage function and call another contract with the parameters from there. + + \ No newline at end of file diff --git a/content/course/interchain-messaging/04-icm-basics/05-receiving-a-message.mdx b/content/course/interchain-messaging/04-icm-basics/05-receiving-a-message.mdx index 757256c8..4d624d6b 100644 --- a/content/course/interchain-messaging/04-icm-basics/05-receiving-a-message.mdx +++ b/content/course/interchain-messaging/04-icm-basics/05-receiving-a-message.mdx @@ -89,3 +89,5 @@ contract MessageReceiver is ITeleporterReceiver { ``` This contract stores the last `Message` and it's sender of each chain it has received. When it is instantiated, the address of the Interchain Messaging contract is supplied to the constructor. The contract implements the `ITelepoterReceiver` interface and therefore we also implement the `receiveTeleporterMessage` function. + + \ No newline at end of file diff --git a/content/course/interchain-messaging/06-invoking-functions/02-encoding-multiple-values.mdx b/content/course/interchain-messaging/06-invoking-functions/02-encoding-multiple-values.mdx index 16346e0a..dd35e793 100644 --- a/content/course/interchain-messaging/06-invoking-functions/02-encoding-multiple-values.mdx +++ b/content/course/interchain-messaging/06-invoking-functions/02-encoding-multiple-values.mdx @@ -90,3 +90,4 @@ Here we are using `abi.decode()` to unpack the three values `(someString, someNu address someAddress ) = abi.decode(message, (string, uint, address)); // [!code highlight] ``` + \ No newline at end of file diff --git a/content/course/interchain-messaging/06-invoking-functions/06-encoding-function-name.mdx b/content/course/interchain-messaging/06-invoking-functions/06-encoding-function-name.mdx index 7687e6c7..37f666fb 100644 --- a/content/course/interchain-messaging/06-invoking-functions/06-encoding-function-name.mdx +++ b/content/course/interchain-messaging/06-invoking-functions/06-encoding-function-name.mdx @@ -248,3 +248,5 @@ cast call --rpc-url myblockchain $RECEIVER_ADDRESS "result_num()(uint)" + + diff --git a/content/course/interchain-messaging/07-icm-registry/02-how-the-icm-registry-works.mdx b/content/course/interchain-messaging/07-icm-registry/02-how-the-icm-registry-works.mdx index b5b71d1e..d669d7a3 100644 --- a/content/course/interchain-messaging/07-icm-registry/02-how-the-icm-registry-works.mdx +++ b/content/course/interchain-messaging/07-icm-registry/02-how-the-icm-registry-works.mdx @@ -79,3 +79,5 @@ contract TeleporterRegistry { ``` If you are interested in the entire implementation, check it out [here](https://github.com/ava-labs/teleporter/blob/main/contracts/teleporter/registry/TeleporterRegistry.sol). + + \ No newline at end of file diff --git a/content/course/interchain-messaging/08-securing-cross-chain-communication/02-signature-schemes.mdx b/content/course/interchain-messaging/08-securing-cross-chain-communication/02-signature-schemes.mdx index 30a571d2..5b7c6747 100644 --- a/content/course/interchain-messaging/08-securing-cross-chain-communication/02-signature-schemes.mdx +++ b/content/course/interchain-messaging/08-securing-cross-chain-communication/02-signature-schemes.mdx @@ -8,4 +8,6 @@ icon: BookOpen import SignatureSchemes from "@/content/common/cryptography/signature-schemes.mdx" - \ No newline at end of file + + + \ No newline at end of file diff --git a/content/course/interchain-messaging/08-securing-cross-chain-communication/04-multi-signature-schemes.mdx b/content/course/interchain-messaging/08-securing-cross-chain-communication/04-multi-signature-schemes.mdx index b5aa4f18..fbdf9922 100644 --- a/content/course/interchain-messaging/08-securing-cross-chain-communication/04-multi-signature-schemes.mdx +++ b/content/course/interchain-messaging/08-securing-cross-chain-communication/04-multi-signature-schemes.mdx @@ -8,4 +8,6 @@ icon: BookOpen import MultiSignatureSchemes from "@/content/common/cryptography/multi-signature-schemes.mdx" - \ No newline at end of file + + + \ No newline at end of file diff --git a/content/course/interchain-messaging/09-avalanche-warp-messaging/02-p-chain.mdx b/content/course/interchain-messaging/09-avalanche-warp-messaging/02-p-chain.mdx index 18e7efc8..08045813 100644 --- a/content/course/interchain-messaging/09-avalanche-warp-messaging/02-p-chain.mdx +++ b/content/course/interchain-messaging/09-avalanche-warp-messaging/02-p-chain.mdx @@ -9,3 +9,5 @@ icon: BookOpen import PChain from "@/content/common/primary-network/p-chain.mdx"; + + diff --git a/content/course/interchain-messaging/09-avalanche-warp-messaging/05-dataflow.mdx b/content/course/interchain-messaging/09-avalanche-warp-messaging/05-dataflow.mdx index 658fdaf5..26798003 100644 --- a/content/course/interchain-messaging/09-avalanche-warp-messaging/05-dataflow.mdx +++ b/content/course/interchain-messaging/09-avalanche-warp-messaging/05-dataflow.mdx @@ -61,3 +61,5 @@ As you noticed in the `Teleporter Basics` chapter most of the cross-chain commun - **Receiving a message:** Being able to be called by the Interchain Messaging on the destination chain To start, we will assume there is always an AWM Relayer to deliver our messages without any incentives. Let's dive deeper into the sending and receiving of messages in the next sections. + + \ No newline at end of file diff --git a/content/course/interchain-messaging/09-avalanche-warp-messaging/06-message-pickup.mdx b/content/course/interchain-messaging/09-avalanche-warp-messaging/06-message-pickup.mdx index 39562fe2..df1625ad 100644 --- a/content/course/interchain-messaging/09-avalanche-warp-messaging/06-message-pickup.mdx +++ b/content/course/interchain-messaging/09-avalanche-warp-messaging/06-message-pickup.mdx @@ -55,4 +55,6 @@ For the source Avalanche L1s, the AWM Relayer offers the following configuration - **message-contracts:** A map with the address of the Interchain Messaging contract as key and the following config parameters as values: - **message-format:** A string specifying the format. Currently, only the format "teleporter" exists, but this field has been added in anticipation of multiple formats in the future - **settings:** A dictionary with settings for this Interchain Messaging contract - - **reward-address:** The address rewards are paid out to \ No newline at end of file + - **reward-address:** The address rewards are paid out to + + \ No newline at end of file diff --git a/content/course/interchain-messaging/09-avalanche-warp-messaging/07-message-delivery.mdx b/content/course/interchain-messaging/09-avalanche-warp-messaging/07-message-delivery.mdx index 52524e63..d59dad42 100644 --- a/content/course/interchain-messaging/09-avalanche-warp-messaging/07-message-delivery.mdx +++ b/content/course/interchain-messaging/09-avalanche-warp-messaging/07-message-delivery.mdx @@ -61,4 +61,6 @@ The BLS public key aggregation has to be done by every validator of the destinat Even though this would make the verification much faster, there is a security issue here. How can we be sure that the aggregated public key actually represents the public keys of the signing validators? How do we know that the AWM Relayer did not just create a bunch of public keys and an aggregated signature of these? -The only way to verify that is to aggregate the public keys of the signing validators and compare it to the one sent by the AWM Relayer. Therefore, it is pointless to attach it to the message. \ No newline at end of file +The only way to verify that is to aggregate the public keys of the signing validators and compare it to the one sent by the AWM Relayer. Therefore, it is pointless to attach it to the message. + + \ No newline at end of file diff --git a/content/course/interchain-messaging/12-incentivizing-a-relayer/02-fee-data-flow.mdx b/content/course/interchain-messaging/12-incentivizing-a-relayer/02-fee-data-flow.mdx index fa0477d4..c68e95b8 100644 --- a/content/course/interchain-messaging/12-incentivizing-a-relayer/02-fee-data-flow.mdx +++ b/content/course/interchain-messaging/12-incentivizing-a-relayer/02-fee-data-flow.mdx @@ -49,4 +49,6 @@ We are using the following emoji guide to show the actors of each action: As you can see, there are just a few actions you as a cross-chain dApp developer need to implement so dApp works smoothly with fees, everything else is being done by the Interchain Messaging contract and the Relayer. -If you run your own relayer, you don't have to attach any fees. \ No newline at end of file +If you run your own relayer, you don't have to attach any fees. + + \ No newline at end of file diff --git a/content/course/interchain-messaging/12-incentivizing-a-relayer/03-determining-the-fee-amount.mdx b/content/course/interchain-messaging/12-incentivizing-a-relayer/03-determining-the-fee-amount.mdx index f9980a28..9cc34044 100644 --- a/content/course/interchain-messaging/12-incentivizing-a-relayer/03-determining-the-fee-amount.mdx +++ b/content/course/interchain-messaging/12-incentivizing-a-relayer/03-determining-the-fee-amount.mdx @@ -59,3 +59,5 @@ Then: *Amount = 550,000,000,000,000 weiTLP* All amounts in Solidity need to be declared in wei, so use a unit converter to convert from nTLP to wei (10^-18). + + \ No newline at end of file diff --git a/content/course/interchain-messaging/certificate.mdx b/content/course/interchain-messaging/certificate.mdx new file mode 100644 index 00000000..c2c1726d --- /dev/null +++ b/content/course/interchain-messaging/certificate.mdx @@ -0,0 +1,14 @@ +--- +title: Course Completion Certificate +updated: 2024-10-11 +authors: [owenwahlgren] +icon: BadgeCheck +--- + +import CertificatePage from '@/components/certificates'; + +You've made it to the end of the course. Let's check your progress and get your certificate. + + + +Thank you for participating in this course. We hope you found it informative and enjoyable! \ No newline at end of file diff --git a/content/course/interchain-messaging/meta.json b/content/course/interchain-messaging/meta.json index 02ba750e..66273d73 100644 --- a/content/course/interchain-messaging/meta.json +++ b/content/course/interchain-messaging/meta.json @@ -24,6 +24,8 @@ "---Restricting-the-relayer---", "...11-restricting-the-relayer", "---Incentivizing a Relayer---", - "...12-incentivizing-a-relayer" + "...12-incentivizing-a-relayer", + "---Conclusion---", + "certificate" ] }