bitpro가 원문에서 글자만 모은 내용이에요. 표·그림·수식은 빠지거나 깨질 수 있어요. 전체 75쪽 중 62쪽
anche, remains infeasible.
Traditional bridges exist to address this limitation by enabling the transfer of
digital assets, such as USDC, across blockchains. However, these bridges come
with significant drawbacks. Two common methods, lock-and-mint bridging and
liquidity pool bridging, require locking USDC liquidity in third-party smart
contracts. This approach reduces capital efficiency and introduces additional
trust assumptions.
## Design Approach
As a low-level primitive, CCTP V1 can be embedded within any app or wallet -
even existing bridges - to enhance and simplify the user experience for
cross-chain use cases. With USDC circulating across a large number of blockchain
networks, CCTP V1 can connect and unify liquidity across disparate ecosystems
where it's supported.
CCTP V1 is built on generalized message passing and designed for composability,
enabling a wide range of use cases. Developers can extend its functionality
beyond just moving USDC between blockchains. For example, you can create a flow
where USDC is sent across chains and automatically deposited into a DeFi lending
pool after the transfer, allowing it to generate yield in an automated manner.
This experience can be designed to feel like a seamless, single transaction for
the end user.
## How CCTP V1 works
**Standard Transfer** is the default method in CCTP V1 for transferring USDC
across blockchains, which involves burning USDC on the source chain and minting
it on the destination chain. It relies on transaction finality on the source
chain and uses Circle's Attestation Service to enable standard-finality
(<Tooltip>hard
finality</Tooltip>) transfers. The process includes the following steps:
1. **Initiation**. A user accesses an app powered by CCTP V1 and initiates a
Standard Transfer of USDC, specifying the recipient's wallet address on the
destination chain.
2. **Burn Event**. The app facilitates a burn of the specified USDC amount on
the source blockchain.
3. **Attestation**. Circle's Attestation Service observes the burn event and,
after observing hard finality on the source chain, issues a signed
attestation. Hard finality ensures the burn is irreversible (about 13 to 19
minutes for Ethereum and L2 chains.)
4. **Mint Event**. The app retrieves the signed attestation from Circle and uses
it to mint USDC on the destination chain.
5. **Completion**. The recipient wallet address receives the newly minted USDC
on the destination blockchain, completing the transfer.
**Standard Transfer** prioritizes reliability and security, making it suitable
for scenarios where finality wait times are acceptable.
## Use Cases
CCTP V1 enables developers to build novel cross-chain apps that integrate
functionalities like trading, lending, payments, NFTs, and gaming, while
simplifying the user experience. Below are some practical examples of how you
can leverage CCTP V1 in your applications, either directly or indirectly by
routing USDC behind the scenes:
### Cross-chain rebalancing
Market makers, fillers/solvers, exchanges, and bridges can use CCTP V1 to manage
liquidity more efficiently. By securely rebalancing USDC holdings across
blockchains, you can reduce operational costs, meet demand, and take advantage
of market opportunities with minimal latency.
### Cross-chain swaps
With CCTP V1, users can quickly swap between digital assets on different
blockchains by routing through USDC. Users can also swap for USDC and
automatically trigger subsequent actions on the destination chain, enabling
seamless cross-chain transactions.
### Cross-chain purchases
Automate cross-chain purchases with CCTP V1. For example, a user can use USDC on
one chain to purchase an NFT on a decentralized exchange on another chain and
list it for sale on an NFT marketplace. When the transaction is initiated, CCTP
V1 routes USDC across chains to buy the NFT and opens the listing on the
marketplace—all in one streamlined flow.
### Simplify cross-chain complexities
Simplify the cross-chain experience by using USDC as collateral on one chain to
open a borrowing position on a lending protocol on another chain. With CCTP V1,
USDC can move quickly between blockchains, allowing users to onboard to new
applications without switching wallets or managing multi-chain complexities.
# CCTP Aptos packages and interfaces V1
Source: https://developers.circle.com/cctp/v1/aptos-packages
Packages for CCTP V1 support on the Aptos blockchain
<Warning>
**This is CCTP V1 version. For the latest version, see [CCTP](/cctp)**.
</Warning>
## Overview
The CCTP V1 Aptos smart contract implementation is written in
[Move](https://aptos.dev/en/build/smart-contracts). The Aptos CCTP V1
implementation is split into two packages: `MessageTransmitter` and
`TokenMessengerMinter`. `TokenMessengerMinter` encapsulates the functionality of
both `TokenMessenger` and `TokenMinter` contracts on EVM chains. To ensure
alignment with EVM contracts logic and state, and to facilitate future upgrades
and maintenance, the code and state of the Aptos packages reflect the EVM
counterparts as closely as possible.
The key difference with Aptos packages from EVM and other CCTP V1
implementations is the receive message flow. Since the Move language uses static
dispatch and requires all dependencies to be available at compile time, the
`MessageTransmitter` `receive_message` function cannot call into the receiver
package (e.g. `TokenMessengerMinter` for USDC transfers). The workaround for
this limitation is that callers of `message_transmitter::receive_message` must
also atomically (in the same transaction or
[move script](https://aptos.dev/en/build/smart-contracts/scripts)) call into the
receiver package's `handle_receive_message` function with a Receipt object
returned from `receive_message`, and then pass a `Receipt` object back into the
`message_transmitter::complete_receive_message` function to complete the message
and destroy the `Receipt` object. Please see the interface and examples below
for more information on this flow.
Below are the known package IDs and object IDs on Aptos testnet and mainnet.
### Testnet
#### Package IDs
| Package | [Domain](/cctp/v1/supported-domains) | Address |
| :- | :- | :- |
| MessageTransmitter | 9 | `0x081e86cebf457a0c6004f35bd648a2794698f52e0dde09a48619dcd3d4cc23d9` |
| TokenMessengerMinter | 9 | `0x5f9b937419dda90aa06c1836b7847f65bbbe3f1217567758dc2488be31a477b9` |
#### Object IDs
| Object | Object ID |
| :- | :- |
| MessageTransmitter | `0xcbb70e4f5d89b4a37e850c22d7c994e32c31e9cf693e9633784e482e9a879e0c` |
| TokenMessengerMinter | `0x1fbf4458a00a842a4774f441fac7a41f2da0488dd93a43880e76d58789144e17` |
| Stablecoin | `0x69091fbab5f7d635ee7ac5098cf0c1efbe31d68fec0f2cd565e8d168daf52832` |
CCTP V1 and Stablcoin use a shared package `AptosExtensions` deployed at
`0xb75a74c6f8fddb93fdc00194e2295d8d5c3f6a721e79a2b86884394dcc554f8f`
### Mainnet
#### Package IDs
| Package | [Domain](/cctp/v1/supported-domains) | Address |
| :- | :- | :- |
| MessageTransmitter | 9 | `0x177e17751820e4b4371873ca8c30279be63bdea63b88ed0f2239c2eea10f1772` |
| TokenMessengerMinter | 9 | `0x9bce6734f7b63e835108e3bd8c36743d4709fe435f44791918801d0989640a9d` |
#### Object IDs
| Object | Object ID |
| :- | :- |
| MessageTransmitter | `0x45bf7f71e44750f2b2a7a1fea21fc44b4a83ba5d68ab10c7a3935f6d8cbdbc75` |
| TokenMessengerMinter | `0x9e6702a472080ea3caaf6ba9dfaa6effad2290a9ba9adaacd5af5c618e42782d` |
| Stablecoin | `0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b` |
The shared package `AptosExtensions` is deployed at
`0x98bce69c31ee2cf91ac50a3f38db7b422e3df7cdde9fe672ee1d03538a6aeae0`
## Interface
The Aptos CCTP V1 source code is
[available on GitHub](https://github.com/circlefin/aptos-cctp/).
The interface below serves as a reference for permissionless messaging functions
exposed by the programs.
### TokenMessengerMinter
#### [deposit\_for\_burn](https://github.com/circlefin/aptos-cctp/blob/master/packages/token_messenger_minter/sources/token_messenger/token_messenger.move#L123)
Burns passed in `FungibleAsset` from sender to be minted on the destination
domain. Minted tokens will be transferred to `mint_recipient` on the destination
chain. The `mint_recipient` can be an account address or a store address. The
`deposit_for_burn` interface and functionality is very similar to the EVM
implementation. The asset parameter is the key difference due to how passing
tokens around on Aptos works. The asset parameter is Aptos Fungible Asset type,
defining information of the token to deposit and burn.
Nonce reserved for the message is returned, but it is not required to do
anything with this return value, they are returned for convenience.
**Parameters**
| Field | Type | Description |
| :- | :- | :- |
| caller | `Signer` | Signer executing the transaction |
| asset | `FungibleAsset` | Asset to be burned. |
| destination\_domain | `u32` | Destination domain identifier. |
| mint\_recipient | `address` | Address of mint recipient on destination domain. Can be an account address or [store address](https://aptos.dev/en/build/smart-contracts/fungible-asset#managing-stores-advanced). *Note: If destination is a non-Move chain,* `mint_recipient` *address should be converted to hex and passed in using the @0x123 address format.* |
#### [deposit\_for\_burn\_with\_caller](https://github.com/circlefin/aptos-cctp/blob/master/packages/token_messenger_minter/sources/token_messenger/token_messenger.move#L147)
The same as deposit\_for\_burn, but with an additional parameter:
`destination_caller`. This parameter specifies which address has permission to
call `receiveMessage` on the destination domain for the message.
**Parameters**
| Field | Type | Description |
| :- | :- | :- |
| caller | `Signer` | Signer executing the transaction |
| asset | `FungibleAsset` | Asset to be burned. |
| destination\_domain | `u32` | Destination domain identifier. |
| mint\_recipient | `address` | Address of mint recipient on destination domain. Can be an account address or [store address](https://aptos.dev/en/build/smart-contracts/fungible-asset#managing-stores-advanced). *Note: If destination is a non-Move chain,* `mint_recipient` *address should be converted to hex and passed in using the @0x123 address format.* |
| destination\_caller | `address` | Address of caller on destination chain. |
<Note>
**Destination Caller Notes**
If the `destination_caller` does not represent a valid address, then it will not
be possible to broadcast the message on the destination domain. This is an
advanced feature, and the standard `deposit_for_burn` should be preferred for
use cases where a specific destination caller is not required.
*Note: If destination is a non-Move chain,* `destination_caller` *address should
be converted to hex and passed in using the @0x123 address format.*
</Note>
#### [replace\_deposit\_for\_burn\_with](https://github.com/circlefin/aptos-cctp/blob/master/packages/token_messenger_minter/sources/token_messenger/token_messenger.move#L171)
Replace a BurnMessage to change the mint recipient and/or destination caller.
Allows the sender of a previous BurnMessage (created by `deposit_for_burn` or
`deposit_for_burn_with_caller`) to send a new BurnMessage to replace the
original.
**Remarks:**
* Only the sender of the original `deposit_for_burn` transaction has access to
call `replace_deposit_for_burn`
* The new `BurnMessage` will reuse the amount and burn token of the original,
without requiring a new `FA` deposit.
* The resulting mint will supersede the original mint, as long as the original
mint has not confirmed yet onchain.
* A valid attestation is required before calling this function.
* This is useful in situations where the user specified an incorrect address and
has no way to safely mint the previously burned USDC.
**Parameters**
| Field | Type | Description |
| :- | :- | :- |
| caller | `Signer` | Signer executing the transaction |
| original\_message | `vector<u8>` | Original message bytes (to replace). |
| original\_attestation | `vector<u8>` | Original attestation |
| new\_destination\_caller | `Option<address>` | The new destination caller, which may be the same as the original destination caller, a new destination caller, or an empty destination caller, indicating that any destination caller is valid. |
| new\_mint\_recipient | `Option<address>` | The new mint recipient, which may be the same as the original mint recipient, or different. |
#### [handle\_receive\_message](https://github.com/circlefin/aptos-cctp/blob/master/packages/token_messenger_minter/sources/token_messenger/token_messenger.move#241)
Handles an incoming message that has already been verified by
`message_transmitter`, and mints USDC to the recipient for valid messages. This
function can only be called with a mutable reference to a `Receipt` object,
which can only be created via a call with a valid message to the
`message_transmitter::receive_message` function. In this function
`MessageTransmitter::complete_receive_message` is called with the `Receipt` to
emit the `MessageReceived` event to complete the message and destroy Receipt.
This should be called in a single transaction after calling
`message_transmitter::receive_message`. EOAs can execute these functions in a
single
[Move script](https://github.com/circlefin/aptos-cctp/blob/master/packages/token_messenger_minter/scripts/handle_receive_message.move#L5).
See the Examples section for the entire flow of receiving a message.
**Parameters**
| Field | Type | Description |
| :- | :- | :- |
| receipt | `Receipt` | Receipt struct returned by `message_transmitter:receive_message` |
### MessageTransmitter
#### [receive\_message](https://github.com/circlefin/aptos-cctp/blob/master/packages/message_transmitter/sources/message_transmitter.move#L287)
Receives a message emitted from a source chain. Messages with a given `nonce`
can only be received once for a (sourceDomain, destinationDomain) pair.
This function returns a `Receipt` struct
([Hot Potato](https://medium.com/@borispovod/move-hot-potato-pattern-bbc48a48d93c))
after validating the attestation and marking the nonce as used. In order to
destroy the `Receipt` and complete the message, in a single transaction,
`handle_receive_message()` must be called with the `Receipt` in the receiver
package. EOAs can execute these functions in a single
[Move script](https://github.com/circlefin/aptos-cctp/blob/master/packages/token_messenger_minter/scripts/handle_receive_message.move#L5).
Returns a `Receipt` object that must be handled by the intended receiving
package, and completed via a `complete_receive_message` call before the
transaction ends. See the
[Examples](/cctp/v1/transfer-usdc-on-testnet-from-aptos-to-base) section for
more information on receiving USDC transfers.
**Parameters**
| Field | Type | Description |
| :- | :- | :- |
| caller | `Signer` | Signer executing the transaction |
| message\_bytes | `vector<u8>` | Message bytes |
| attestation | `vector<u8>` | Attestation |
#### [complete\_receive\_message](https://github.com/circlefin/aptos-cctp/blob/master/packages/message_transmitter/sources/message_transmitter.move#L330)
Completes the message by emitting a `MessageReceived` event for a receipt and
destroying the receipt.
**Parameters**
| Field | Type | Description |
| :- | :- | :- |
| caller | `Signer` | Signer for the `receipt.recipient` address |
| receipt | `Receipt` | Receipt struct to be destroyed |
#### [send\_message](https://github.com/circlefin/aptos-cctp/blob/master/packages/message_transmitter/sources/message_transmitter.move#L169)
Sends a message to the destination domain and recipient. Nonce reserved for the
message is returned, but it is not required to do anything with this struct, it
is returned for convenience.
**Remarks:**
* For USDC transfers, this function is called directly by the
`TokenMessengerMinter` package in `deposit_for_burn()`.
**Parameters**
| Field | Type | Description |
| :- | :- | :- |
| caller | `Signer` | Signer for executing the transaction |
| destination\_domain | `u32` | Destination domain identifier. |
| recipient | `address` | Recipient address. *Note: If destination is a non-Move chain,* `recipient` *address should be converted to hex and passed in using the @0x123 address format.* |
| message\_body | `vector<u8>` | Message to be sent to destination chain |
#### [send\_message\_with\_caller](https://github.com/circlefin/aptos-cctp/blob/master/packages/message_transmitter/sources/message_transmitter.move#L198)
This is the same as send\_message, except the `receive_message` call on the
destination domain must be called by `destination_caller`.
**Parameters**
| Field | Type | Description |
| :- | :- | :- |
| caller | `Signer` | Signer for executing the transaction |
| destination\_domain | `u32` | Destination domain identifier. |
| recipient | `address` | Recipient address. *Note: If destination is a non-Move chain,* `recipient` *address should be converted to hex and passed in using the @0x123 address format.* |
| destination\_caller | `address` | Address of caller on destination chain. |
| message\_body | `vector<u8>` | Message to be sent to destination chain |
<Note>
**Destination Caller Notes**
If the `destination_caller` does not represent a valid address, then it will not
be possible to broadcast the message on the destination domain. This is an
advanced feature, and the standard `deposit_for_burn` should be preferred for
use cases where a specific destination caller is not required.
*Note: If destination is a non-Move chain,* `destination_caller` *address should
be converted to hex and passed in using the @0x123 address format.*
</Note>
#### [replace\_message](https://github.com/circlefin/aptos-cctp/blob/master/packages/message_transmitter/sources/message_transmitter.move#L229)
Replace a message with a new message body and/or destination caller. The
originalAttestation must be a valid attestation of originalMessage, produced by
Circle's attestation service.
**Remarks:**
* Only the sender of the original deposit\_for\_burn transaction has access to
call `replace_message`
**Parameters**
| Field | Type | Description |
| :- | :- | :- |
| caller | `Signer` | Signer executing the transaction |
| original\_message | `vector<u8>` | Original message bytes (to replace). |
| original\_attestation | `vector<u8>` | Original attestation |
| new\_message\_body | `Option<vector<u8>>` | New message body |
| new\_destination\_caller | `Option<address>` | The new destination caller, which may be the same as the original destination caller, a new destination caller, or an empty destination caller, indicating that any destination caller is valid. |
## Additional Notes
### Using Move Scripts
Pre-compiled scripts for executing `deposit_for_burn` and
`handle_receive_message` are available in the
[repo](https://github.com/circlefin/aptos-cctp/tree/master/typescript/example/precompiled-move-scripts)
for testnet and mainnet. Alternatively, the scripts can be compiled from the
source code. The documentation can be found on the official Aptos
[website](https://aptos.dev/en/build/smart-contracts/scripts/compiling-scripts).
### Mint Recipient Addresses for Aptos as Source Chain
Outgoing mint recipient addresses from Aptos are passed as Aptos address types
and can be treated the same as a `bytes32` mint recipient parameter on EVM
implementations.
### Mint Recipient Addresses for Aptos as Destination Chain
Aptos mint recipient addresses from other chains should be treated the same as a
hex `bytes32` parameter.
# CCTP API hosts and endpoints V1
Source: https://developers.circle.com/cctp/v1/cctp-apis
API hosts and endpoints for CCTP V1
<Warning>
**This is CCTP V1 version. For the latest version, see [CCTP](/cctp)**.
</Warning>
CCTP V1 provides a set of API hosts and endpoints to manage messages,
attestations, and transaction details for your cross-ch프로젝트로 돌아가기