- Create a facet transaction to a global/main/single facet-deployed contract (could be factory for creating L2 nft contracts)
- In facet data pass the ethscription ids, similar to how we do ESIP-5
- Ethscriptions indexers detects transactions to this facet contract, easily by just inspecting transaction's input calldata hex
Somethig like that
function sendTx({ chainId, to, value, gasLimit, data, mineBoost }: any) {
const transactionData = [
toHex(chainId ?? 1),
to ?? '0x',
value ? toHex(value) : '0x',
gasLimit ? toHex(gasLimit) : '0x',
data ?? '0x',
mineBoost ?? '0x',
];
const encodedTransaction = concatHex([toHex(70), toRlp(transactionData)]);
console.log(encodedTransaction);
// => 0x46f85b0194 1111000000000000000000000000000000001111
// 8080b840 01eee5be1b69d05322456d2664116422e8e04faf8e45f5ad6a054a5723c04c7e a992926edc1f701adc4ab9f5d035d35d6399948c75e16d3895204aa08b5cd64380
}
sendTx({
to: '0x1111000000000000000000000000000000001111', // some nft contract address
// "bridging" these ethscriptions
// 0x01eee5be1b69d05322456d2664116422e8e04faf8e45f5ad6a054a5723c04c7e
// 0xa992926edc1f701adc4ab9f5d035d35d6399948c75e16d3895204aa08b5cd643
data: '0x01eee5be1b69d05322456d2664116422e8e04faf8e45f5ad6a054a5723c04c7ea992926edc1f701adc4ab9f5d035d35d6399948c75e16d3895204aa08b5cd643',
});
This sends a transaction to a facet contract, calling the fallback
function, with the data containing the ethscription ids to be transferred.
Now, we may also need to prefix the Ethscription IDs, with a burn address, and the rest are ethscription ids.
So in that fallback we can check if the first 20 bytes are the burn address, and if so, we know it's a transfer, and we consider the transfers/bridge-in to be valid. Then when emitting Transfer events like ESIP-1/2 we can pass that burn address as param to previousOwner
or from
field.
eg.
0x46f85b0194
1111000000000000000000000000000000001111 - facet contract
8080b840
2222000000000000000000000000000000002222 - burn address (could just be the 0x000..face7 too)
01eee5be1b69d05322456d2664116422e8e04faf8e45f5ad6a054a5723c04c7e a992926edc1f701adc4ab9f5d035d35d6399948c75e16d3895204aa08b5cd64380
So, Ethscriptions indexer can detect transactions calldata that starts with 0x46f85b0194
and has a known burn address, eg. /^0x46f85b0194.+2222000000000000000000000000000000002222.+/
. Set that burn address as current_owner
for the given ethscription ids.
Then, on withdrawal, Ethscriptions indexer listen for ESIP-1/2 events through Facet RPC like it does for the L1 cases.
In fact, this even allows for "real-time" transferring. I mean, for every L2 transfer/sale/whatever it could just emit valid ESIP-1/2 event and it's automatically respected in Ethscriptions protocol too. Thus, it's not right to call the L2 contract "a bridge" or anythign like that, it's just an NFT contract, that in addition to the normal erc721 transfer, it also emit esip-1/2 events 🤯
Basically, users choose to what nft contract to "bridge", tho it's not bridging, it's temporary place where the ethscription is assigned.
In that facet contract's fallback
function, you convert the ethscription ids to integers so they become the tokenIds
, so the ERC721 tokenURI
just returns esc://content/:tokenId
or baseURI() + tokenId
where each facet market platform could resolve from any Ethscriptions API considering it has /content/:bigint endpoint resolving to that ethscriptions content with toHex(bigint) -> txHash
. This esc://content/
Ethscriptions endpoint, which could be included in ESIP-9 "API Endpoints" draft, allows NFT contracts to use setBaseURI('esc://content/')
.
Also btw, we should skip ESIP9, it's for exactly API endpoints and stuff.