aelf Oracle Episode 3: DEMO
ELF contract on Ethereum — approve the transaction
The Ethereum address approves the LockMapping contract, allowing the contract to transfer its ELF tokens. This step is used to prepare for the upcoming createReceipt transaction.
LockMapping contract on Etherem — createReceipt transaction
In addition to throwing corresponding events, the LockMapping contract completes the following three things in this transaction:
1. Transfer a certain amount of ERC-20 ELF tokens to the contract;
2. Create a Receipt object and store it in the contract;
3. Assign an ID to the newly created Receipt, store the address whose value is the uint256 array.
Now that the above-mentioned Receipt has been added to Ethereum’s WorldState, all we need to do is to wait for aelf oracle do its transporting work.
aelf Oracle contract — Query transaction
aelf oracle node will periodically call the receiptCount interface of the Ethereum LockMapping contract during the aelf mainnet token swap. The result will be compared and match with the recorded in the aelf MerkleTreeRecorder contract. If it is found that a new receipt is generated by the LockMapping contract, the Query transaction is created using the id of the recently generated receipt.
As shown in the aelf blockchain browser, during the currency swap process, the parameter structure of the Query transaction is as follows:
In this process, the periodically scanning node has informed other nodes with the Query transaction that the hash values of the four Receipts with id 0 to 3 are now needed.
After the Query transaction is successfully packaged by the aelf blockchain, the QueryCreated event will be thrown immediately. The details of the event are as follows:
aelf Oracle contract — 5 Commit transactions
The following transaction will be executed under the order of the Commit transaction：
Oracle node (Gn2……fbo)：https://explorer.aelf.io/tx/ae3827b9a6f46b05d408f4156a02968a7439705e6fcc4264024a3d58033eda63
Oracle node (xWe……57e)：https://explorer.aelf.io/tx/3333ad4f72a934978d12c81e1f72c784659118c560e73ea4349bbce011a7a7ca
Oracle node (2cG……DUc)：https://explorer.aelf.io/tx/b44b44bfbbdffebdca9d8e426be4f1229194db459035a3fe1870354b8f0ea845
Oracle node (2eS……xez)：https://explorer.aelf.io/tx/3c12eeb11f60053175d79c615de315598cb0e2f249458c5d05b62e34aa63dcbf
Oracle node (3W7……2LT)：https://explorer.aelf.io/tx/d98c54686612fad0294f6839acc2a8b32d0d8da7f330149d8adcd38d88c54288 (Note: A Log named SufficientCommitmentsCollected appeared in this Commit transaction)
After the five aelf oracle nodes configured the QueryCreated event with the title “record_receipts” on the chain, they will query the getReceiptInfo interface of the Ethereum LockMapping contract. According to the instructions of queryInfo/options in the QueryCreated event, they need to query the details of four receipts with ids from 0 to 3. Then getReceiptInfo will return three pieces of data:
1. The hash value of the corresponding id (this is useless);
2. The receiving address on aelf blockchain when creating Receipt;
3. The number of ERC20 ELF locked by the user when creating Receipt.
After obtaining the above three data, the aelf oracle node starts to construct a Commit transaction by the following order:
- Hash the last two of the above three pieces of data, and then hash this hash value with the locally randomly generated “salt” again;
- Use the hash value finally obtained as commitment.
The five oracle nodes will submit their Commit transactions. Therefore, although on the Ethereum LockMapping contract, the data of the four receipts from 0 to 3 are unique, five oracle nodes will generate five different commitments.
Commitment of oracle node (Gn2……fbo) is 447df09c52d86adefb7e4d82c18859214763dc7f4fa9ee8931acf80f8f6481b9
Commitment of oracle node (xWe……57e) is 43ee4f144db59eb2262ff32ff34dee2f27e2033c7ce9ecddb0252ad5b05764b6
aelf Oracle contract — 3 successful Reveal contract
Execute by the Reveal transaction order:
Oracle node (3W7……2LT): https://explorer.aelf.io/tx/83f5cf744710de034efe3440dfaf151fcff36fe4ccecbf60a39230bee2341d37
Oracle node (2eS……xez): https://explorer.aelf.io/tx/5b9aee7f10fb583eda1071b5cee7a469ad47429bb76c98a8ddd90c46a90370c5
Oracle node (2cG……DUc): https://explorer.aelf.io/tx/d0e99c82223a76291410e93d4aca8fff18d08bf6763dcc80d8cb60a32bc2e835
The three Reveal transactions above show Reveal data in common. And the hash values of data and salt of Reveal transaction parameters are consistent with commitment (otherwise the Reveal transaction will fail due to hash mismatch).
Additionally, the largest workload is the third Reveal transaction, because the execution of this Reveal transaction marks the official completion of the receipt of the four ids from 0 to 3.
It can be seen from the Logs of this Reveal transaction:
- Three Transferred events: The payment was distributed equally to three nodes who successfully executed the Reveal transaction;
- CommitmentRevealed event: Throw out the query result and announce the completion of the query process;
- QueryCompletedWithAggregation event: Indicate that the results have been aggregated;
- MerkleTreeRecorded event: This event is thrown from the Oracle contract’s callback of the callback information provided by the callback_info of the Query transaction parameter after the query process is over.
aelf Oracle oracle — A failed Reveal transaction
Oracle node (Gn2……fbo): https://explorer.aelf.io/tx/4dabc5137ae8c5868985bcef787054da7182d62754e4a7de9dd7cc1726e2650b
So how could a Reveal transaction fails? Let’s go through the error message:
“AElf.Sdk.CSharp.AssertionException: Query already finished.”
It indicates that before the execution of the transaction, the correspondent Query has ended.
When the Query ends, the value of aggregate_threshold becomes an important parameter. In the mainnet swap event, this value was not set. As a result, the Oracle contract automatically calculated the recommended aggregate_threshold (which is 3), based on the number of nodes (5).
By analyzing the parameters and Logs of the Query transaction, it can be seen that aggregate_threshold is not set to 3 in the parameters, but aggregate_threshold is set to 3 in the QueryCreated event.
Up to now, all four nodes have sent Reveal transactions, what about the other node? The oracle node “xWe……57e” sent Commit transactions, but it was not found in the blockchain browser that he sent Reveal transactions. In fact, this oracle node also constructed and broadcast Reveal transactions on demand, but because its transaction was broadcast too late and was blocked by a full node in the pre-execution Verifying.
aelf Bridge contract — SwapToken transaction
With the completion of 11 successful transactions on both aelf mainnet and on the Ethereum, we finally came to the last step: receives ELF mainnet tokens. Or in other words, executes the SwapToken method of the Bridge contract.
The swap website will automatically fill in the following three parameters:
- swapId: The only marker;
- receiptId: The ID of the receipt;
- originAmount: The amount of ERC-20 tokens locked.
In the SwapToken transaction, the Bridge contract verifies the hash value of the originAmount and the sender of the transaction. Once confirmed, the corresponding amount of mainnet ELF tokens will be sent to the user’s aelf account.