Open AlexRipoll opened 9 months ago
In blockchains where the time between block production is known, knowing the timestamp of the 1st block you can easily deduct all the timestamps for different blocks. In the first cases where the universalnode is used, both ownership and evolutionchain should follow that pattern.
This proposal is to have theEvochain events be related to the latest block that was already produced in that timestamp in the ownership chain. The main reason in order to take this approach is that, while the blockchain is producing blocks, you can always know to which ownership block a current event emitted in the evochain is related to and add it there. A problem that this approach has is that you might ask information from the latest block to the universal node that might not be completed with all the evochain information and that might change in a few seconds.
This proposal is to have theEvochain events be related to the next block that was produced in that timestamp in the ownership chain. The main reason in order to take this approach is that when a new ownershipchain block is produced, it will already have all the events of the evochain inside. A problem that this approach has is that despite some events will be happening in the evochain, the universal node will not be able to add them until a new ownershipchain block is produced.
I believe option 2 is better since this way all the information that you get when you get when you ask for an ownershipchain block to the universal node will always be completed with the evochain information.
Option 1 In this proposal, we argue to always round the evolution chain block to the nearest ownership block that happened BEFORE. In the previous example:
Option 2 In this proposal, we argue to always round the evolution chain block to the nearest ownership block that happened AFTER. In the previous example:
Proposed improvements:
Nomenclature: change "transformed events" to "included events" everywhere.
Add to the intro: "This specification is essentially many-to-one. It must include evoChain events for every ownership contract that points to those events. The mapping is many-to-one.
Add to the intro: "Currently, there is only support for 2 types of events from the Evochain: mint & evolve". A mint must produce an ERC721 Transfer event from the null address, and an evolve must produce a MetadataUpdate event as specified by ERC4096.
transactionIndex
: change the current sentence to: "the transaction from the evochain is appended as the last transaction in the block, which fixes the transactionIndex". Remove any reference to "events" in this row, since they are not relevant
Blockhash
: clarify by rephrasing to: "original unmodified hash of the ownership chain block where the events are included"
BlockNumber
: clarify by rephrasing to: "Block number of the ownership chain determined by the mapping function defined below"
data
: clarify by specifying at the end. "Data payload with the non indexed arguments from the ERC721 event. For Mints, this field is null (0x
) since all args in the Transfer event are indexed. For a change in URI, the event is MetadataUpdate
.
topics
. Make more explicit: "As mandatory, Topics[0]
is the hash of the signature of the event. For a mint event, which translates to an ERC721 Transfer event, the value must be 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
. For a MetadataUpdate
event, the value must be: TODO-ADD
"
Add this formula as pseudocode. Any different implementation must be return the same values. It has the following properties:
// evoTimestamp is the timestamp of the evochain block where the event to be included what included
// ownTimestamps is an array: ownTimestamps[n] returns the timestamp of an ownershipChain blocknumber n
function ownChainBlockNumber(uint evoTimestamp, uint[] ownTimestamps) {
uint n = ownershipContractCreationBlocknumber;
while (n < lastProducedOwnchainBlocknumber) {
if (ownTimestamps[n+1] > evoTimestamp) return n;
n++;
}
return n;
}
Please reconsider the sentence under "Considerations". The inclusion, or lack of inclusion, of that event, and other evochain events, is completely unrelated to the order in which things happen.
Also, please apply chatGPT for corrections in grammar and to make several sentences more concise. One example: "This table pretends to explain how each evochain event will be included to a standard ERC721 event" ==> "This table intends to explain how each evochain event will be mapped to a standard ERC721 event".
I also suggest to change the name of this issue, so that it becomes simply the place where people come to find the spec, now that there's nothing else to clarify.
Description
When transaction logs are requested from the Universal Node (uNode), the following behaviour is expected:
The latter events must be included following the standards:
mint
must produce an ERC721 Transfer event from the null address,evolve
must produce a MetadataUpdate event as specified by ERC4096.Events are just returned as part of the queries, they are by no means included in the storage of the Ownership Chain.
This specification is essentially many-to-one: Evochain events must be included for every UniversalERC721 contract in the Ownership Chain whose Universal Location points to the same Evochain collection
Specification
The table below lists the fields of the Event structure, provides descriptions of their intended uses, and specifies the construction of values for the
mint
andevolve
cases as previously outlined.removed
true
: The log was removed due to a chain reorganization.false
: Valid log.transactionIndex
null
when the log is pending.transactionIndex
.logIndex
null
when the log is pending.transactionIndex
transactionHash
null
when the log is pending.transactionHash
from the Evochain - This allows users to locate the transaction in the EvochainblockHash
null
when the log is pending.blockNumber
null
when the log is pending.address
data
mint
: null (0x
), since all args in theTransfer
event are indexed. Forevolve
, the non-indexeduint256 tokenId
arg ofMetadataUpdate
.topics
Topics[0]
is the hash of the signature of the event: for amint
the value of aTransfer
(0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
). For anevolve
, the value of aMetadataUpdate
(0xf8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7
). Finally, for amint
the rest of topics1,...,3
include the 3 indexed arguments of the event (from, to, tokenId
).Determination of
blockNumber
in Ownership ChainEvents from TXs produced in the Evochain will be returned as part of the queries for events from Universal ERC721 contracts in the Ownership Chain. The Ownership Chain
blockNumber
will be determined by comparison of timestamps between both chains. Even if clocks and timestamps are, of course, completely independent in both chains, the mapping must be deterministic.The mapping returns Evochain events as part of the next block produced in the Ownership Chain, where next is derived from timestamp comparison. The specified mapping has the following properties:
blockNumber
at which the Universal ERC721 contract was deployed. It therefore prevents events from being included before the contract was created.The following pseudocode serves as reference. Any implementation must produce the same results.
Event Arguments
The following table provides details on the determination of the arguments in the included events.
MintedWithExternalURI(address indexed to, uint96 slot, uint256 indexed tokenId, string tokenURI)
Transfer (index_topic_1 address 0, index_topic_2 address to, index_topic_3 uint256 tokenId)
EvolvedWithExternalURI(uint256 indexed tokenId, string tokenURI)
MetadataUpdate(uint256 tokenId)
NewCollection(address indexed owner, address collectionAddress)