Source Chain Smart Contracts
What is a Source Chain Smart Contract?
Section titled “What is a Source Chain Smart Contract?”A source chain smart contract is a contract living on a source chain such as
Ethereum that is supported by the
Creditcoin Oracle. Source chain contracts have two main responsibilities:
- Support any source chain logic required by their Universal dApp.
- Emit events that contain the data their dApp needs to verify and process on Creditcoin
Let’s focus on these one by one.
Source chain logic
Section titled “Source chain logic”Most logic and data for Universal DApps should live in contracts on Creditcoin rather than the source chain. Keep source chain logic minimal—typically just enough to handle asset movements (e.g., burning tokens, locking assets) and emit events.
Best practices:
- Minimize source chain logic to reduce gas costs and complexity
- Keep business logic on Creditcoin
- So that data and liquidity from many chains can be used in one place
- And to benefit from lower transaction + storage costs
- Use source chain contracts primarily for emitting events that trigger cross-chain actions
Emitting Events
Section titled “Emitting Events”This is the way by which the source chain will communicate with Creditcoin. When a source chain contract emits an event, it becomes part of the transaction’s receipt logs, which can be cryptographically verified on Creditcoin.
Imagine that you want a simple dApp which burns ERC20 tokens on Ethereum and mints corresponding ERC20 tokens on Creditcoin. Then you would want your source chain smart contract to emit an event such as TokensBurnedForBridging.
Event design considerations:
- Use
indexedparameters for efficient filtering (up to 3 indexed parameters) - Include all data the dApp needs in the event parameters
- Keep event signatures consistent to simplify parsing in USC contracts
Example Source chain contract
Section titled “Example Source chain contract”The following example shows a simple ERC20 contract that supports a token bridge dApp. When tokens are “burned” (transferred to a burn address), a custom TokensBurnedForBridging event is emitted, which can be verified on Creditcoin to trigger token minting.
Key features:
- Emits a custom
TokensBurnedForBridgingevent for easy filtering by offchain workers - Uses a burn address (
0x...01) to represent token burning - The
TokensBurnedForBridgingevent includes all necessary data (from,value) - Workers can easily filter for this specific event signature and then generate proofs to submit to the USC contract
// SPDX-License-Identifier: MITpragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract TestERC20 is ERC20 { address public constant BURN_ADDRESS = address(1); // 0x...01
/// @notice Emitted when tokens are burned (sent to the burn address). /// @param from The address burning their tokens /// @param value The amount of tokens burned event TokensBurnedForBridging(address indexed from, uint256 value);
constructor() ERC20("Burn Test", "TEST") { // Mint sender initial supply _mint(msg.sender, 1_000_000 ether); }
/// @notice "Burn" by transferring tokens to the 0x...01 sink address. /// @dev This does NOT reduce totalSupply; it only makes tokens inaccessible. /// @param amount The amount of tokens to burn /// @return success Whether the transfer succeeded function burn(uint256 amount) external returns (bool) { _transfer(msg.sender, BURN_ADDRESS, amount); emit TokensBurnedForBridging(msg.sender, amount); return true; }}