Open YamenMerhi opened 1 year ago
lgtm. the only thing i was thinking of is
0000
separator we could have a dedicated byte that will let the verifier know whether it is a "double" or "single" type verification but since the standard is made for offchain agents I guess it is not a big deal to verify directly.This sounds like a very interesting idea!
Maybe the first dynamic part of the data key can be chainId of the other chain to resolve to?
We could also use uint32
or uint64
for the type, but consider the max value allowed for a chainId based on EIP2294: https://eips.ethereum.org/EIPS/eip-2294#:~:text=Due%20to%20how%20the%20calculation,the%20highest%20value%20is%20used.
So the data key would look like:
"name": "LSP24MultichainAddressResolution:<uint32>:<address|bytes32>",
Also for the second part of the data key, could the bytes32
correspond to the contract code hash?
https://docs.soliditylang.org/en/v0.8.20/cheatsheet.html#members-of-address
The data value stored under this data key is the address in the native format of the network of the address resolved. Each network could have a different representation of the address encoding, for example, bitcoin address encoding is different than EVM address encoding.
Great idea to store as bytes
for this purpose! 👌
After further research, a proposal could be to construct the chainId instead of the bytes4 representation for EVM chains. In this way, chains don't need to take a step to standardize a representation but it's already done with knowing the chainId of the EVM Network
To be reviewed to include a more generic address resolution while taking into consideration: 1-
{
"name": "LSP24MultichainAddressResolution:<bytes4>:<address|bytes32>",
"key": "0x049b19b87a61<bytes4>00<address>",
"keyType": "MappingWithGrouping",
"valueType": "bytes",
"valueContent": "Address|Bytes"
}
Simplification to
{
"name": "LSP24MultichainAddressResolution:<bytes8>:<address>",
"key": "0x049b19b8<bytes8><address>",
"keyType": "Custom",
"valueType": "bytes",
"valueContent": "Address|Bytes"
}
As the bytes32 lookup can happen by:
2 - No explicit bound for the type of chainId
--> Probably Standardizing Registry for ChainIds,
Not All chainIds needs to be represented as there is a lot of Testnets that die eventually
3 - Address Resolution on Non-EVM chain
4 - Calldata
or txFormat
to resolve to the address on a specific chain according to the Sepcs of the Chain
5 - Have different type of dataValues, for example based on the first byte:
0x00
--> Defines an Address to be resolved0x01
--> Defines a calldata
to be executed on a specific chain0x02
--> Defines a txFormat
to be simulated in the other Blockchain Network0x03
--> Defines a way to reference - and a way to reverse verifyThe standard can continue to evolve To be Tested with Bitcoin, Solana, Cardano, XRP ..
Is it stale?
Proposing a standard related to Multichain Address Resolution to start by querying the storage of an ERC725Y contract. The resolution can happen to the ERC725Y contract itself, or other addresses. Verification of the resolution will be based on the ERC725Y contract on both chains, by making the ERC725Y contracts point to each other
To have a background of how the resolution happens with ENS: https://eips.ethereum.org/EIPS/eip-2304
Feedback about the logic of the standard is welcomed (not typo/grammatical/vocab error as this is not a PR) 🤝
lip: ? title: Multichain Address Resolution author: [Your Name] <[Your Email]> discussions-to: status: Draft type: LSP created: 2023-06-19 requires: ERC725Y, LSP2
Simple Summary
This standard describes a set of ERC725Y data key-value pairs that allow resolution of addresses on different chains, and a mechanism for verifying the claim of address resolution.
Abstract
The
LSP24MultichainAddressResolution
data key will allow resolution of addresses on other chains based on an address or a standard hash.Motivation
For EVM chains, if an address is an Externally Owned Account (EOA) it is known that the controller of this EOA can control it across different chains. But for smart contracts it's different, even with having contracts at the same address across different chains, it's possible to have different contracts, which makes having a contract at same address on different chains does not guarantee that these contracts are the same.
It is essential to have a mechanism that resolve an address from a chain to another one, making it possible to resolve contract addresses to their equivalents on other EVM chains, and normal addresses to other chains, even non EVM ones such as Bitcoin, Ripple, Solana, etc..
Specification
Address Resolution
Every contract that supports the LSP24MultichainAddressResolution standard MUST have the following data key:
LSP24MultichainAddressResolution
The data key is constructed from 2 dynamic parts:
bytes4
which represent the chain of the address resolvedaddress
to lookup on another chain or a bytes32 hash of a specific standard.The data value stored under this data key is the address in the native format of the network of the address resolved. Each network could have a different representation of the address encoding, for example, bitcoin address encoding is different than EVM address encoding.
The bytes4 chain representation and its respective address encoding can be found and added to the table at the end of the specification. For example:
Example 1
Suppose an ERC725Y contract deployed on LUKSO Mainnet, and we want to resolve its corresponding address on Ethereum Mainnet. Here's how we would proceed:
We start by identifying the bytes4 representation of the Ethereum Mainnet chain, let's say for instance, it's
0xffffffff
.Next, we need the address of the ERC725Y contract on LUKSO Mainnet. In our example, let's consider it to be
0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
.Using the above details, we can construct the data key as follows:
0x049b19b87a61ffffffff00aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
.After retrieving the data stored under this key, let's say we got
0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
. This implies that the ERC725Y contract's address on LUKSO Mainnet is0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
, and the corresponding address of this contract on the Ethereum Mainnet is0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
.Example 2
There could be the case where a lookup is needed for a specific standardized wallet, for example a wallet standardized under the name of
XYZ50
:We start by identifying the bytes4 representation of the chain to lookup, let's say for instance, it's
0xffffffff
.Next, we need the hash standardized for the wallet. In our example, it can be standardized as the keccak256 of
XYZ50
equal to0x1e647dad4813ed23203d95b2d3ab27ea25a4c1a2ed45c3002dc063fe9f4a14a4
Using the above details, we can construct the data key as follows:
0x049b19b87a61ffffffff001e647dad4813ed23203d95b2d3ab27ea25a4c1a2
.After retrieving the data stored under this key, let's say we got
0xcccccccccccccccccccccccccccccccccccccccc
. This implies that the walletXYZ50
on the chain looked up is at the address0xcccccccccccccccccccccccccccccccccccccccc
.Example 3
There could be the case where a lookup is needed for an address on a non EVM chain such as Bitocin. Here's how we would proceed:
We start by identifying the bytes4 representation of the chain to lookup, let's say for instance, it's Bitcoin and its chain representation is
0xbbbbbbbb
.Next, we need the address to lookup. In our example, let's consider it to be
0x2222222222222222222222222222222222222222
.Using the above details, we can construct the data key as follows:
0x049b19b87a61bbbbbbbb002222222222222222222222222222222222222222
.After retrieving the data stored under this key, let's say we got
0x0062e907b15cbf27d5425399ebf6f0fb50ebb88f18
. Given that the encoding of Bitcoin addresses is based onP2PKH
(base58check), after decoding the address resolved will be1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
.Verifying Address Resolution
While it's relatively simple to claim that a certain address on another chain is the corresponding address or under the same control, this can potentially lead to deceptive assertions, causing major problems. Therefore, it's essential to have a standardized mechanism for verifying such address resolution claims.
For verification purposes, the ERC725Y contract should exist on the chain to lookup. To verify that the resolution is correct, it is essential to have the same reverse lookup happen on the lookup chain. In this way, we have a resolution that could go in both ways, making it possible and sure that these 2 contracts are under the same control and point to each other.
This method represents an autonomous way for verifying the claim of address resolution, but other solutions such as verifying signature on the address looked up could also be used.
Example 4
Continuing with the example 1, the ERC725Y contract on the Ethereum chain at address
0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
should store a data key pointing back to the LUKSO network.Supposing the bytes4 representation of LUKSO Mainnet is
0x42424242
, the data key0x049b19b87a614242424200bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
should exist in the ERC725Y contract on the Ethereum Mainnet , and the data value stored under the data key should be equal to0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
.Example 5
In case where the lookup is not intended for the ERC725Y contract itself, the verification process will require few more steps.
If the lookup in the ERC725Y contract deployed on LUKSO Mainnet is for a vault address to be checked on Ethereum Mainnet, then the lookup start with:
We start by identifying the bytes4 representation of the Ethereum Mainnet chain, let's say for instance, it's
0xffffffff
.Next, we need the address of the vault contract on LUKSO Mainnet. In our example, let's consider it to be
0xdddddddddddddddddddddddddddddddddddddddd
.Using the above details, we can construct the data key as follows:
0x049b19b87a61ffffffff00dddddddddddddddddddddddddddddddddddddddd
.After retrieving the data stored under this key, let's say we got
0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
. This implies that the vault contract's address on LUKSO Mainnet is0xdddddddddddddddddddddddddddddddddddddddd
, and the corresponding address of this contract on the Ethereum Mainnet is0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
.The verification phase cannot go directly to
0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
as this contract could be not implementing ERC725Y and just representing a vault. To have a verified resolution, we need a reverse lookup using the ERC725Y contract.The ERC725Y should be available on the chain to lookup, in our case Ethereum Mainnet, and should be resolved from LUKSO Mainnet and should be pointing back to the LUKSO address on Ethereum Mainnet as shown in Example 4.
After verfying that the ERC725Y contracts on Ethereum and LUKSO point to each other, the verification to the vault happens as follows:
We start by identifying the bytes4 representation of the LUKSO Mainnet chain, let's say for instance, it's
0x42424242
.Next, we need the address of the vault contract on Ethereum Mainnet. In our example above, we got it as
0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
.Using the above details, we can construct the data key as follows:
0x049b19b87a614242424200eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
.The data stored under this data key should be equal to
0xdddddddddddddddddddddddddddddddddddddddd
. This implies that the vault contracts on LUKSO Mainnet and Ethereum Mainnet are pointing and referencing each other through the ERC725Y contract existing on both chains.In this way, a resolution that could go in both ways is established, making it possible to verify that these two contracts are under the same control and point to each other.
Rationale
The process of verification of address resolution autonomously may only be available for specific networks. Some networks do not have the capability to support contracts or storage, thus address resolution can be implemented, but not verification.
The standard does not enforce the process of creating the
bytes4
representation of the chain. It is up to each chain to standardize theirbytes4
representation. This approach can support a significant number of chains, up to 4,294,967,295.The decision not to make the
bytes4
as thechainId
representation is because some networks havechainId
that are larger than 4 bytes. Additionally, choosing not to use the hash of the network name or currency is due to the potential hash collisions.Therefore, it's essential for each chain to add their representation to LSP24, while reviewing the already used
bytes4
chain representations.Implementation
ERC725Y JSON Schema
LSP24MultichainAddressResolution
:List of Chains and Encoding
Chains can be added here:
Copyright
Copyright and related rights waived via CC0.